[Topologic] Redefining BIM through Spatial Topology, Information, and Grammars

12022242526

Comments

  • edited April 2022

    Pseudo code. Syntax may not be 100% correct (Sorry on my phone not computer):
    import topologic
    # get some object from scene. Call it obj
    cc = topologic.Topology.ByOCCTShape(obj)
    internal_faces = []
    external_faces = []
    all_faces = []
    _ = cc.Faces(None, all_faces)
    for face in all_faces:
    cells = []
    _ = face.Cells(cc, cells)
    if len(cells) > 1:
    internal_faces.append(face)
    else:
    external_faces.append(face)

    paullee
  • Test file - Rename the file to *.FCstd to open in FreeCAD

  • @topologic said:
    Your best source is the python code at:
    https://github.com/wassimj/TopologicSverchok/tree/main/nodes/Topologic
    You can look at the function “processItem” in each file and find out how Topologic Python works

    Thanks! Lots of reading available over the weekend :D

    topologic
  • Only work with ... topologic.Topology.ByString() in FreeCAD python console :)

    c=Gui.Selection.getSelection()[0]
    cbs=c.Shape.exportBrepToString()
    cc=topologic.Topology.ByString(cbs)

    topologic.Topology.ByOCCTShape(obj) seems not working

    # get some object from scene. Call it obj
    cc = topologic.Topology.ByOCCTShape(obj)
    

    c=Gui.Selection.getSelection()[0]
    cc=topologic.Topology.ByOcctShape(c)

    Traceback (most recent call last):
    File "", line 1, in
    TypeError: ByOcctShape(): incompatible function arguments. The following argument types are supported:
    1. (rkOcctShape: topologic.TopoDS_Shape, rkInstanceGuid: str = '') -> topologic.Topology
    Invoked with:

    Then _=cc.Faces(None, faces)

    faces=[]
    cc

    topologic.Cluster object at 0x7fee535841f0

    _=cc.Faces(None, faces)

    Traceback (most recent call last):
    File "", line 1, in
    TypeError: Faces(): incompatible function arguments. The following argument types are supported:
    1. (self: topologic.Cluster, rFaces: list) -> None
    Invoked with: <topologic.Cluster object at 0x7fee535841f0>, None, []

    Will go through more *.py in your github :D

  • In FreeCAD python console, how do you get an object and its shape from the scene?

  • edited April 2022

    Thanks.

    'Selection set 1st document object '
    s=Gui.Selection.getSelection()[0]

    'shape in FreeCad'
    ss=s.Shape

    'export the shape as Brep String'
    ssbs=s.Shape.exportBrepToString()

  • edited April 2022

    Gone through half of the *.py there, found no use of this as reference :D

    topologic.Topology.ByOCCTShape(obj)

    EDIT - seem no relevant info here either :
    https://topologic.app/user_doc/html/class_topologic_1_1_topology.html

    FURTHER EDIT -
    Noted there is :
    https://github.com/wassimj/TopologicSverchok/blob/main/nodes/Topologic/TopologyByOCCTShape.py

    Hmmm, but do not understand how the 'OCCTShape' is generated and pass to the method :D

  • Hi @paullee I don’t understand how you found 100s of the main python files that drive all of TopologicSverchok of no use! @brunopostle was able to rewrite homemaker using Topologic without documentation. Not ideal obviously, but achievable.
    In any case, I need resources/volunteers to write a set of documentation. I will investigate auto-generated documentation. Anyone willing to help?

    Note: OCCTShape is a DS_Shape. If it doesn’t work stick with the brep string method

  • edited April 2022

    @topologic said:
    Hi @paullee I don’t understand how you found 100s of the main python files that drive all of TopologicSverchok of no use! @brunopostle was able to rewrite homemaker using Topologic without documentation. Not ideal obviously, but achievable.
    In any case, I need resources/volunteers to write a set of documentation. I will investigate auto-generated documentation. Anyone willing to help?

    Note: OCCTShape is a DS_Shape. If it doesn’t work stick with the brep string method

    My problem in fact, not your codes :D

    I am just python beginner and no idea on Blender nor OCCT programming, so I find there are codes on topologic.Topology.ByOCCTShape(obj) but do not understand how similar 'obj' be generated in FreeCAD, not in Blender then I think I can just 'copy and paste' :D. I also find ' topologic.Topology.ByString(BRep String Output from FreeCAD - I find how to do this only) return no error, though still looking around to see how the returned object be used to verified if it is useful at all.

    The answers I am searching around are -
    1) how to export to 'OCCTShape' in FreeCAD, googling but find not solution yet
    2) is the object returned by topologic.Topology.ByString(BRep String Output from FreeCAD) useful and usage of methods

    Still googling, trial and errors, thanks again for the time taken :D

  • I am asking in FreeCAD forum how to export to 'OCCTShape' in FreeCAD after hours of my wild guess :D

  • I hope this helps. First create two cubes in FreeCAD and offset them as you see in the picture on the left. Then select both and run the code below.

    import topologic
    import Part
    s=Gui.Selection.getSelection()
    c1 = s[0]
    c2 = s[1]
    tc1 = topologic.Topology.ByString(c1.Shape.exportBrepToString())
    tc2 = topologic.Topology.ByString(c2.Shape.exportBrepToString())
    print(tc1, tc2)
    tc3 = tc1.Difference(tc2)
    print(tc3)
    tc3 = topologic.TopologyUtility.Translate(tc3, 15, 0, 0)
    shp3 = Part.Shape()
    shp3.importBrepFromString(tc3.String())
    Part.show(shp3)
    tc4 = tc1.Intersect(tc2)
    print(tc4)
    tc4 = topologic.TopologyUtility.Translate(tc4, 30, 0, 0)
    shp4 = Part.Shape()
    shp4.importBrepFromString(tc4.String())
    Part.show(shp4)
    tc5 = tc2.Difference(tc1)
    print(tc5)
    tc5 = topologic.TopologyUtility.Translate(tc5, 45, 0, 0)
    shp5 = Part.Shape()
    shp5.importBrepFromString(tc5.String())
    Part.show(shp5)
    tc6 = tc1.Merge(tc2)
    print(tc6)
    tc6 = topologic.TopologyUtility.Translate(tc6, 60, 0, 0)
    shp6 = Part.Shape()
    shp6.importBrepFromString(tc6.String())
    Part.show(shp6)

    paulleebrunopostle
  • edited April 2022

    @paullee And here is how you get the internal and external faces of a CellComplex. For this example, start by modelling two cubes and put them side by side where they exactly touch. Then run the script below. See the image at the bottom for more explanation.

    import topologic
    import Part

    def get_internal_faces(cellComplex):
    internal_faces = []
    faces = []
    _ = cellComplex.Faces(None, faces)
    for face in faces:
    cells = []
    _ = face.Cells(cellComplex, cells)
    if len(cells) > 1:
    internal_faces.append(face)
    return topologic.Cluster.ByTopologies(internal_faces)

    def get_external_faces(cellComplex):
    external_faces = []
    faces = []
    _ = cellComplex.Faces(None, faces)
    for face in faces:
    cells = []
    _ = face.Cells(cellComplex, cells)
    if len(cells) < 2:
    external_faces.append(face)
    return topologic.Cluster.ByTopologies(external_faces)

    s=Gui.Selection.getSelection()
    c1 = s[0]
    c2 = s[1]
    tc1 = topologic.Topology.ByString(c1.Shape.exportBrepToString())
    tc2 = topologic.Topology.ByString(c2.Shape.exportBrepToString())
    print(tc1, tc2)
    tc3 = tc1.Merge(tc2)
    print(tc3)
    tc3 = topologic.TopologyUtility.Translate(tc3, 25, 0, 0)
    shp3 = Part.Shape()
    shp3.importBrepFromString(tc3.String())
    obj3 = Part.show(shp3)
    obj3.Label = "CellComplex"
    obj3.ViewObject.Transparency=50

    tc4 = get_internal_faces(tc3)
    tc4 = topologic.TopologyUtility.Translate(tc4, 25, 0, 0)
    shp4 = Part.Shape()
    shp4.importBrepFromString(tc4.String())
    internal_faces = Part.show(shp4)
    internal_faces.Label = "Internal Faces"
    internal_faces.ViewObject.Transparency=50

    tc5 = get_external_faces(tc3)
    tc5 = topologic.TopologyUtility.Translate(tc5, 50, 0, 0)
    shp5 = Part.Shape()
    shp5.importBrepFromString(tc5.String())
    external_faces = Part.show(shp5)
    external_faces.Label = "External Faces"
    external_faces.ViewObject.Transparency=50

    paulleebrunopostle
  • edited April 2022

    @topologic said:
    tc1 = topologic.Topology.ByString(c1.Shape.exportBrepToString())
    shp3.importBrepFromString(tc3.String())

    This is really what is needed to start communication between FreeCAD and Topologic !

    In fact, Topologic should be built-in FreeCAD (within the Part API?) , all the methods seems exactly the same and both speaks Brep (as they both based on OpenCascade right?) :D

    • Topologic.Difference is FreeCAD.Part Shape1.cut(Shape2)
    • Topologic.Intersect is FreeCAD.Part Shape1.common(Shape2) ...

    Just did a roundtrip test between FreeCAD Part.Shape to Topologic, made a translation in Topologic and return to FreeCAD. These 2 methods are the keys.

    I can understand the rest of the codes by the way ! Thanks again for taking time mentoring !

    topologicbrunopostle
  • Yes. I have always said that whatever Topologic can do, can be achieved in FreeCAD. One can actually learn the methods we have in Topologic and re-implement them using the FreeCAD API. In fact, when we were developing Topologic, I would at times test the concept using python in FreeCAD, show it to the team and they would write it in C++ directly using the opencascade engine. We made a decision early on to reduce the dependencies and go directly to opencascade (because we wanted a base in C++). If I had time and resources, I can re-build Topologic completely using FreeCAD and, as you said, the Part workbench.

    paullee
  • @topologic said:
    ... If I had time and resources, I can re-build Topologic completely using FreeCAD and, as you said, the Part workbench.

    Time and resources are always the keys. It is a shame what is achievable in Blender, e.g. Sverchok-Topologic, is not present in FreeCAD, at the moment :D

    topologic
  • Stuck at this line at the moment.

    _ = cellComplex.Faces(None, faces)

    Can find the same line below, so it should be working, but why not in my FreeCAD ...?
    https://github.com/wassimj/TopologicSverchok/blob/main/nodes/Topologic/TopologyRemoveCoplanarFaces.py

    Trying to workaround by importing all individual faces from FC, instead of returning from the topology...

    tc5 = get_external_faces(tc3)
    Traceback (most recent call last):
    File "", line 1, in
    File "", line 4, in get_external_faces
    TypeError: Faces(): incompatible function arguments. The following argument types are supported:
    1. (self: topologic.CellComplex, rFaces: list) -> None
    Invoked with: <topologic.CellComplex object at 0x7f7518263030>, None, []

  • I believe you are still using an obsolete version of Topologic.
    If the following works then you are definitely using an obsolete version:
    faces = []
    _ = tc3.Faces(faces)

  • Hmm, not working either. Difference in versions of Python, OCC maybe.

    cells=[]
    tcc
    ... topologic.CellComplex object at 0x7f74f80ecd30
    tcc.Faces
    ... bound method PyCapsule.Faces of <topologic.CellComplex object at 0x7f74f80ecd30>

    tcc1sf1
    ... topologic.Face object at 0x7f74f80e8eb0

    _=tcc1sf1.Cells(tcc, cells)
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: Cells(): incompatible function arguments. The following argument types are supported:
    1. (self: topologic.Face, rCells: list) -> None

    Invoked with: <topologic.Face object at 0x7f74f80e8eb0>, <topologic.CellComplex object at 0x7f74f80ecd30>, []

  • Now I am 100% convinced that you are using the obsolete version of Topologic. Has nothing to do with OCC or python. Just your Topologic version is several months old.

    paullee
  • Random test other some other methods, seems working

    tcc1s
    ... topologic.Cell object at 0x7f7518266a70
    tcc1s.Cells
    ... bound method PyCapsule.Cells of <topologic.Cell object at 0x7f7518266a70
    topologic.CellUtility.Volume(tcc1s)
    ... 999.9999999999998

  • Oh, should be this ?

    topologic.CellComplex.Faces(tcc, faces)
    faces
    [<topologic.Face object at 0x7f74f80eca30>, <topologic.Face object at 0x7f751825f670>, <topologic.Face object at 0x7f753e1496b0>, <topologic.Face object at 0x7f753e149f30>, <topologic.Face object at 0x7f753e149e30>, <topologic.Face object at 0x7f753e149470>, <topologic.Face object at 0x7f753e149fb0>, <topologic.Face object at 0x7f753e14a030>, <topologic.Face object at 0x7f753e14a070>, <topologic.Face object at 0x7f753e149bb0>, <topologic.Face object at 0x7f753e14a0b0>]

  • Now, similar error with this line.. trying CellUtility instead ... :)

       _ = face.Cells(cellComplex, cells)
    
  • @paullee said:
    Random test other some other methods, seems working

    tcc1s
    ... topologic.Cell object at 0x7f7518266a70
    tcc1s.Cells
    ... bound method PyCapsule.Cells of <topologic.Cell object at 0x7f7518266a70
    topologic.CellUtility.Volume(tcc1s)
    ... 999.9999999999998

    Yes. Most methods didn’t change so they would work. But don’t let that deceive you. You are 100% using an obsolete version of Topologic

  • edited April 2022

    @topologic said:
    Now I am 100% convinced that you are using the obsolete version of Topologic. Has nothing to do with OCC or python. Just your Topologic version is several months old.

    I see. This is somehow 'extracted' from Brunopostle Copr seems 'incorrectly', seem I needs to do good housekeeping on that part first :D

    But it is good news, seems things are working :D

  • It seems I found the correct Fedora 34 version from Brunopostle finally :D

    topologicbrunopostle
  • @paullee said:
    It seems I found the correct Fedora 34 version from Brunopostle finally :D

    Excellent!!

  • Dear OSArch community,
    I am happy to announce that I have added to Topologic the ability to communicate with Speckle from within sverchok. I know they have a Blender connector, but it is not expressed as svertchok nodes and has some serious limitations (e.g. user-defined custom attributes are not included)
    This means that we can now send Revit objects right through Sverchok. I will be posting more about the use case scenario over the next few days and weeks.

    paulleeAcebruno_perdigaobasweingokermudimitar
  • @paullee said:
    It seems I found the correct Fedora 34 version from Brunopostle finally :D

    There is regression in my FreeCAD version, upgraded and all works as expected :D

    topologicdimitar
  • OK, tested a basic workflow as proof-of-concept.
    The python script to find internal and external faces (walls) works as expected :D

    • Create a 'single-line sketch' layout with an ArchSketch on FreeCAD
    • It automatically generate a series of Solids as volume of spaces
    • Convert the Solids into CellComplex in Topologic
    • Find the external and internal faces of the CellComplex by Topologic method
    • Based on same ArchSketch layout, it can create ArchWall in FreeCAD as well

    'ArchSketch Single-Line Layout' -

    Auto-generated Solids as spaces; Convert to CellComplex in Topologic -

    Found External faces -

    Found Internal faces -

    Build ArchWall based on same ArchSketch -

    brunopostleAcedimitarJanF
  • Great stuff, @paullee !

Sign In or Register to comment.