Open Moult opened 2 years ago
Hey there, Such an integration would be awesome! I'd like to help making that happen.
How would such a redesign be, is there something specific you already imagine?
I think you've said that it should be possible to import the addon or parts of it from another addon, right? How would registration of operators and properties happen in such a scenario?
I'm not quite sure, I haven't yet had the chance to code dive :) IFC supports defining certain types of geometry. One of these is a polycurve consisting of straight lines and arc segments: http://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcIndexedPolyCurve.htm
If I am able to process the IFC polycurve into something that geometry_sketcher can understand, is there some function that can be called to render the profile on the screen so the user can edit it? Once edited, can I insert a callback, listener, hook or perhgaps write my own operator that stops rendering the profile on the screen and receives the edited profile from geometry_sketcher so that I can convert it back into an IFC polycurve?
Would you be available for a short call to discuss and I can demo how things work in IFC and discuss how an integration might work?
I would love to see this as well!
Could see CAD_Sketcher being the in-world editor for all IfcProfileDef's
If you need some simple examples from FreeMVD
IFCRECTANGLEPROFILEDEF schema definition here
/*#237=IFCEXTRUDEDAREASOLID(#231,#235,#236,6.56167979002625);*/
/*#231=IFCRECTANGLEPROFILEDEF(.AREA.,$,$,5.90551160243344,2.62467200889831);*/
/*#235=IFCAXIS2PLACEMENT3D(#232,#233,#234);*/
/*#232=IFCCARTESIANPOINT((2.28083978487751,-2.64041986208888,1.00000011013562));*/
/*#233=IFCDIRECTION((0.,-0.,-1.));*/
/*#234=IFCDIRECTION((-1.,0.,0.));*/
/*#236=IFCDIRECTION((0.,0.,-1.));*/
IFCCIRCLEPROFILEDEF schema definition here
/*#208=IFCEXTRUDEDAREASOLID(#202,#206,#207,2.99999996554407);*/
/*#202=IFCCIRCLEPROFILEDEF(.AREA.,$,#201,0.499189355954731);*/
/*#201=IFCAXIS2PLACEMENT2D(#199,#200);*/
/*#199=IFCCARTESIANPOINT((0.,0.));*/
/*#200=IFCDIRECTION((1.,0.));*/
/*#206=IFCAXIS2PLACEMENT3D(#203,#204,#205);*/
/*#203=IFCCARTESIANPOINT((1.60414813541052E-08,-2.2916401934436E-09,-1.00000069679551));*/
/*#204=IFCDIRECTION((3.7878029957028E-07,2.31496199987191E-09,-1.));*/
/*#205=IFCDIRECTION((-0.0578654408454895,-0.998324334621429,0.));*/
/*#207=IFCDIRECTION((-3.91146457445757E-08,1.79253149212855E-07,-0.999999940395355));*/
IFCARBITRARYPROFILEDEFWITHVOIDS schema definition here
/*#194=IFCEXTRUDEDAREASOLID(#188,#192,#193,3.);*/
/*#188=IFCARBITRARYPROFILEDEFWITHVOIDS(.AREA.,$,#182,(#187));*/
/*#182=IFCPOLYLINE((#178,#179,#180,#181,#178));*/
/*#178=IFCCARTESIANPOINT((-0.500000006179484,-0.49999995729116));*/
/*#179=IFCCARTESIANPOINT((0.500000006179484,-0.49999995729116));*/
/*#180=IFCCARTESIANPOINT((0.500000006179484,0.500000348397753));*/
/*#181=IFCCARTESIANPOINT((-0.500000006179484,0.500000348397753));*/
/*#178=IFCCARTESIANPOINT((-0.500000006179484,-0.49999995729116));*/
/*#187=IFCPOLYLINE((#183,#184,#185,#186,#183));*/
/*#183=IFCCARTESIANPOINT((-0.353553393498806,1.95553296507187E-07));*/
/*#184=IFCCARTESIANPOINT((0.,-0.353553124613023));*/
/*#185=IFCCARTESIANPOINT((0.353553393498806,1.95553296507187E-07));*/
/*#186=IFCCARTESIANPOINT((0.,0.353553613496265));*/
/*#183=IFCCARTESIANPOINT((-0.353553393498806,1.95553296507187E-07));*/
/*#192=IFCAXIS2PLACEMENT3D(#189,#190,#191);*/
/*#189=IFCCARTESIANPOINT((1.77188495325604,0.,2.34991546690933));*/
/*#190=IFCDIRECTION((0.70710676908493,0.,0.70710676908493));*/
/*#191=IFCDIRECTION((0.,1.,0.));*/
/*#193=IFCDIRECTION((0.,0.,1.));*/
IFCARBITRARYCLOSEDPROFILEDEF schema definition here
/*#365= IFCEXTRUDEDAREASOLID(#359,#364,#20,3.);*/
/*#359= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'Generic Models 1',#352);*/
/*#352= IFCCOMPOSITECURVE((#324,#331,#338,#344,#351),.F.);*/
/*#324= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#322);*/
/*#322= IFCPOLYLINE((#318,#320));*/
/*#318= IFCCARTESIANPOINT((-0.500000000000002,-0.5));*/
/*#320= IFCCARTESIANPOINT((0.499999999999998,-0.5));*/
/*#331= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#329);*/
/*#329= IFCPOLYLINE((#325,#327));*/
/*#325= IFCCARTESIANPOINT((0.499999999999998,-0.5));*/
/*#327= IFCCARTESIANPOINT((0.5,0.499999999999998));*/
/*#338= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#336);*/
/*#336= IFCPOLYLINE((#332,#334));*/
/*#332= IFCCARTESIANPOINT((0.5,0.499999999999998));*/
/*#334= IFCCARTESIANPOINT((-0.,0.500000000000001));*/
/*#344= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#341);*/
/*#341= IFCTRIMMEDCURVE(#340,(IFCPARAMETERVALUE(360.)),(IFCPARAMETERVALUE(90.)),.T.,.PARAMETER.);*/
/*#340= IFCCIRCLE(#339,0.5);*/
/*#339= IFCAXIS2PLACEMENT2D(#10,#28);*/
/*#10= IFCCARTESIANPOINT((0.,0.));*/
/*#28= IFCDIRECTION((0.,1.));*/
/*#351= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#349);*/
/*#349= IFCPOLYLINE((#345,#347));*/
/*#345= IFCCARTESIANPOINT((-0.500000000000001,0.));*/
/*#347= IFCCARTESIANPOINT((-0.500000000000002,-0.5));*/
/*#364= IFCAXIS2PLACEMENT3D(#360,#362,#18);*/
/*#360= IFCCARTESIANPOINT((0.353553390593275,0.500000000000007,0.358787223388274));*/
/*#362= IFCDIRECTION((0.707106781186547,0.,0.707106781186548));*/
/*#18= IFCDIRECTION((0.,-1.,0.));*/
/*#20= IFCDIRECTION((0.,0.,1.));*/
IFCISHAPEPROFILEDEF schema definition here
#541=IFCEXTRUDEDAREASOLID(#75,$,#540,2.);
/*#75=IFCISHAPEPROFILEDEF(.AREA.,'This is the profile name',$,0.100000001490116,0.319999992847443,0.00499999988824129,0.00999999977648258,0.00499999988824129,$,$);*/
Apart from the primitives and parametric profiles, I reckon the biggest advantage would be the ability to author IfcIndexedPolyCurve which is effectively a polyline which supports arc segments.
Would you be available for a short call to discuss and I can demo how things work in IFC and discuss how an integration might work?
Yeah sure, how about tomorrow (Wednesday) afternoon?
You can have multiple profiles in one 'mesh', as well.
IFCSHAPEREPRESENTATION schema definition here
/*#246= IFCSHAPEREPRESENTATION(#127,'Body','SweptSolid',(#211,#219,#245));*/
/*#127= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#121,$,.MODEL_VIEW.,$);*/
/*#121= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,0.0001,#118,#119);*/
/*#118= IFCAXIS2PLACEMENT3D(#6,$,$);*/
/*#6= IFCCARTESIANPOINT((0.,0.,0.));*/
/*#119= IFCDIRECTION((6.12303176911189E-17,1.));*/
/*#211= IFCEXTRUDEDAREASOLID(#205,#210,#20,5.);*/
/*#205= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'Generic Models 1',#203);*/
/*#203= IFCPOLYLINE((#197,#199,#201,#197));*/
/*#197= IFCCARTESIANPOINT((-0.5,-0.333333333333333));*/
/*#199= IFCCARTESIANPOINT((0.5,-0.333333333333333));*/
/*#201= IFCCARTESIANPOINT((0.,0.666666666666667));*/
/*#197= IFCCARTESIANPOINT((-0.5,-0.333333333333333));*/
/*#210= IFCAXIS2PLACEMENT3D(#208,#16,#14);*/
/*#208= IFCCARTESIANPOINT((2.49999999999999,-5.,0.333333333333327));*/
/*#16= IFCDIRECTION((0.,1.,0.));*/
/*#14= IFCDIRECTION((-1.,0.,0.));*/
/*#20= IFCDIRECTION((0.,0.,1.));*/
/*#219= IFCEXTRUDEDAREASOLID(#215,#218,#20,5.);*/
/*#215= IFCCIRCLEPROFILEDEF(.AREA.,'Generic Models 1',#214,0.5);*/
/*#214= IFCAXIS2PLACEMENT2D(#212,#24);*/
/*#212= IFCCARTESIANPOINT((-2.84968587332237E-30,-2.27595720048157E-15));*/
/*#24= IFCDIRECTION((1.,0.));*/
/*#218= IFCAXIS2PLACEMENT3D(#216,#16,#12);*/
/*#216= IFCCARTESIANPOINT((4.49999999999999,-5.,0.499999999999985));*/
/*#16= IFCDIRECTION((0.,1.,0.));*/
/*#12= IFCDIRECTION((1.,0.,0.));*/
/*#20= IFCDIRECTION((0.,0.,1.));*/
/*#245= IFCEXTRUDEDAREASOLID(#240,#244,#20,5.);*/
/*#240= IFCARBITRARYPROFILEDEFWITHVOIDS(.AREA.,'Generic Models 1',#228,(#238));*/
/*#228= IFCPOLYLINE((#220,#222,#224,#226,#220));*/
/*#220= IFCCARTESIANPOINT((-0.5,-0.5));*/
/*#222= IFCCARTESIANPOINT((0.5,-0.5));*/
/*#224= IFCCARTESIANPOINT((0.5,0.5));*/
/*#226= IFCCARTESIANPOINT((-0.5,0.5));*/
/*#220= IFCCARTESIANPOINT((-0.5,-0.5));*/
/*#238= IFCPOLYLINE((#230,#232,#234,#236,#230));*/
/*#230= IFCCARTESIANPOINT((-0.25,0.25));*/
/*#232= IFCCARTESIANPOINT((0.25,0.25));*/
/*#234= IFCCARTESIANPOINT((0.25,-0.25));*/
/*#236= IFCCARTESIANPOINT((-0.25,-0.25));*/
/*#230= IFCCARTESIANPOINT((-0.25,0.25));*/
/*#244= IFCAXIS2PLACEMENT3D(#242,#16,#14);*/
/*#242= IFCCARTESIANPOINT((0.499999999999988,-5.,0.5));*/
/*#16= IFCDIRECTION((0.,1.,0.));*/
/*#14= IFCDIRECTION((-1.,0.,0.));*/
/*#20= IFCDIRECTION((0.,0.,1.));*/
So sorry I missed your message @hlorus - I'm online in general in the OSArch chatroom during the Sydney timezone. @qwiglydee is also helping hack on the BlenderBIM Add-on and can also find him online in the chatroom feel free to ping us anytime :)
Essentially to integrate with IFC:
The first profile I'd like to see being able to convert to and from IFC / CAD Sketcher is an IfcIndexedPolyCurve: http://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcIndexedPolyCurve.htm
It's pretty straightforward, essentially a polyline, where a segment may either be a straight line, or a circular arc. So as long as you can translate to and from a list of sequential points, that's all we need. To represent the arc, it is represented by 3 points - the start, end, and point on the arc (let's go for midpoint).
Does this sound achievable? If you can help point us to some functions to call and examples of inputs and outputs, I can help link it up to IFC and @qwiglydee and write the GUI integration and any necessary math to convert arcs and points and so on.
So sorry I missed your message @hlorus
No problem at all!
- What function should we call from the BlenderBIM Add-on to programatically display a profile using cad-sketcher?
Due to the parametric nature of the addon geometry is always represent as bpy properties which get stored to disk. In order to manipulate/access and display this data the addon(or just the properties) have to be registered in blender.
If the addon is registered and enabled there's nothing else required, to display a profile, besides creating the CAD Sketcher data.
- What is the format cad-sketcher needs us to describe the input profile to generate any profile that we need? We can build an IFC Profile->CAD Sketcher Profile converter.
The addons data is defined in class_defines.py, there's some inital documentation here. Data is currently stored on the scene type so everything can be accessed through bpy.context.scene.sketcher. So to describe a profile you would need to add the individual entities with the add functions (e.g. context.scene.sketcher.entities.add_point_3d(position)). Most of the entity types will require other entities and will depend on them(to create a 3d line you have to define two 3d points first).
You'll want to create a sketch to define the profile. A sketch is currently always based on a workplane however you can use one of the origin workplanes: entities = context.scene.sketcher.entities entities.ensure_origin_elements(context) wp = entities.origin_plane_XY sketch = entities.add_sketch(wp)
- After the user modifies that profile what function should we call to stop displaying that editable profile on the screen using CAD sketcher?
Entities have a "visible" property which can be used to hide them. Entities that are part of a sketch will also not be drawn if the sketch is set to not be visible.
Alternatively you could just delete the entities: entities.remove(some_entity.slvs_index) The remove operator also supports deleting a whole sketch recursively: bpy.ops.view3d.slvs_delete_entity(index=sketch.slvs_index)
- What is the output format we can extract of the saved profile? We can build a CAD Sketcher Profile -> IFC Profile converter here.
Conversion simply happens by going through the entities and accessing their properties. I've written a walker (in convertors.py) which can return a list of paths(connected segment entities). This can probably be reused.
For better integration i've looked into adding a event system, there's now a branch for that. Also there's the integration branch which intends to add a basic integration API, what do you think about having CAD Sketcher as a dependency and enabling it from within another addon?
This is awesome and your tips made it easy to integrate! Apologies for the delay, I originally wanted to sponsor work by @qwiglydee to work on this but alas it didn't happen.
I've now done a couple prototype operators to allow editing of arbitrary polyline profiles (i.e. no arcs, circles, etc) with CAD sketcher: https://github.com/IfcOpenShell/IfcOpenShell/commit/4c7a5e8a1a9887bd7696f0872920fdebe4eb66cd just to see what the workflow might be like.
It's a promising start but I have some nagging thoughts that suggest it may not be appropriate for some tasks in the BIM world. The BIM world relies a lot more on non-parametric "arbitrary" locations. Just "move this dot here" for example. It also relies a lot of "move this here to align with this edge/corner/whatever of this other 3D object", which CAD sketcher at its current functionality doesn't do very well compared to the OOTB Blender functions of pushing vertices and edges around. I think this means that CAD sketcher should be provided as one option (which might suite well for assembly style part modeling), but there should also be another method more catered towards the BIM world (for the majority of usecases of simple profile editing for slabs, gutters, skirting, mullion extrusion profiles, etc).
Great to see your efforts, if i get it right you've implemented two operators which allows to temporarily display and edit geometry with the CS tools. The major downside here is that you loose the parametric nature of the addon as all the constraints are removed between the edits.
Referencing of meshes and other entities is indeed a big topic which is already on the roadmap however this might take some time to arrive.
Indeed right now all the parametric nature is lost. This is fine for the prototype, and if further development would occur, all parametric entities would have to be serialised and stored in IFC, and then deserialised on load again, and there would be a job in itself to figure out which ones can play nice with IFC and which can only work in Blender. I think this means this topic needs to be revisited in the future :)
There's now basic support to write out the addon data of a given scene into a file and load it back in, see: https://github.com/hlorus/CAD_Sketcher/commit/7c548e624a725d6bc3760d4648d92d9e1d882371
Here's a testfile to try it: save_load.zip
Awesome :) I've now updated the integration to use the to_dict() and update() methods :) Let's give it a little while to see where users think integration should be pushed, but at least the basics are there.
Excited about this integration. I think the following functionality would make a CadSketcher/BlenderBIM integration more attractive and useful.
@Moult how do you envision eventually codifying these constraints into the IFC file?
Are you thinking it would be similar to what @geometrygym proposed here?
To help with funding, i proposed this project as a possible project for OSArch to center a funding campaign around. https://community.osarch.org/discussion/comment/12859/#Comment_12859
Motivation / Existing Problem IFC is a way of describing parametric geometry in the world of BIM (Building Information Management - basically the schema for digital buildings). Right now there is no nice UX for modifying these parametric profiles in Blender.
Description I'd love to collaborate with the geometry sketcher plugin to integrate with IFC. Would you be interested in a collaboration or redesigning the plugin so it is more agnostic / generic and can be called from other add-ons too?