Generate a cube BRepBody - result is not a body? What's the missing part in the definition?

Generate a cube BRepBody - result is not a body? What's the missing part in the definition?

wh6Q9NU
Advocate Advocate
632 Views
2 Replies
Message 1 of 3

Generate a cube BRepBody - result is not a body? What's the missing part in the definition?

wh6Q9NU
Advocate
Advocate

The body returned from this script is not recognised as a body (for example I can't select it as a body when joining another body).

What could be the missing element in the BRepBody definition? Thanks in advance for any suggestions!

 

#Author-Codemans
#Description-Create cube, rib size 10

from typing import List, Dict, Tuple
import adsk.core, adsk.fusion, adsk.cam, traceback
# from . import utils as utils

def createShellAndFaceAndEdges(
    brepBodyDef :adsk.fusion.BRepBodyDefinition,
    pTopLeft :adsk.core.Point3D,
    pTopRight :adsk.core.Point3D,
    pBotLeft :adsk.core.Point3D,
    pBotRight :adsk.core.Point3D,
):
  # Create lump definition
  lumpDefs = brepBodyDef.lumpDefinitions
  lumpDef = lumpDefs.add()

  # Create shell definition
  shellDefs = lumpDef.shellDefinitions
  shellDef = shellDefs.add()

  # Create face definition
  faceDef = shellDef.faceDefinitions.add(createFrontNurbsSurface(
      pTopLeft,
      pTopRight,
      pBotLeft,
      pBotRight,
  ), True)

  edges :List = createEdges(
      brepBodyDef,
      pTopLeft,
      pTopRight,
      pBotLeft,
      pBotRight,
  )

  # Create loop definition
  loopDef = faceDef.loopDefinitions.add()

  # Create coEdge definitions
  for edgeDef in edges:
      loopDef.bRepCoEdgeDefinitions.add(edgeDef, True)

def createEdge(
  brepBodyDef :adsk.fusion.BRepBodyDefinition,
  p0 :adsk.core.Point3D,
  p1 :adsk.core.Point3D,
) -> adsk.fusion.BRepCoEdgeDefinition:
  v0 :adsk.fusion.BRepVertexDefinition = brepBodyDef.createVertexDefinition(p0)
  v1 :adsk.fusion.BRepVertexDefinition = brepBodyDef.createVertexDefinition(p1)

  return brepBodyDef.createEdgeDefinitionByCurve(v0, v1, adsk.core.Line3D.create(p0, p1))

def createEdges(
  brepBodyDef :adsk.fusion.BRepBodyDefinition,
  pTopLeft :adsk.core.Point3D,
  pTopRight :adsk.core.Point3D,
  pBotLeft :adsk.core.Point3D,
  pBotRight :adsk.core.Point3D,
) -> List[adsk.fusion.BRepCoEdgeDefinition]:
  edges :List[adsk.fusion.BRepCoEdgeDefinition] = []

  edges.append(createEdge(brepBodyDef, pTopLeft, pBotLeft))
  edges.append(createEdge(brepBodyDef, pBotLeft, pBotRight))
  edges.append(createEdge(brepBodyDef, pBotRight, pTopRight))
  edges.append(createEdge(brepBodyDef, pTopRight, pTopLeft))

  return edges

def createFrontNurbsSurface(
  pTopLeft :adsk.core.Point3D,
  pTopRight :adsk.core.Point3D,
  pBotLeft :adsk.core.Point3D,
  pBotRight :adsk.core.Point3D,
) -> adsk.core.NurbsSurface:
    
    degreeU = 1
    degreeV = 1
    controlPointCountU = 2
    controlPointcountV = 2

    controlPoints = [pTopLeft, pTopRight, pBotLeft, pBotRight]

    knotsU = (0, 0, 1, 1)
    knotsV = (0, 0, 1, 1)
    weights = ()
    propertyU = 1
    propertyV = 1

    surface :adsk.core.NurbsSurface = adsk.core.NurbsSurface.create(
      degreeU,
      degreeV,
      controlPointCountU,
      controlPointcountV,
      controlPoints,
      knotsU,
      knotsV,
      weights,
      propertyU,
      propertyV,
    )

    return surface

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        # Create a new document
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        
        # Create a base feature
        rootComp = design.rootComponent

        brepBodyDef :adsk.fusion.BRepBodyDefinition = adsk.fusion.BRepBodyDefinition.create()

        pTopFrontLeft = adsk.core.Point3D.create(-5, 5, 5)
        pTopFrontRight = adsk.core.Point3D.create(5, 5, 5)
        pBotFrontLeft = adsk.core.Point3D.create(-5, -5, 5)
        pBotFrontRight = adsk.core.Point3D.create(5, -5, 5)

        pTopBackLeft = adsk.core.Point3D.create(-5, 5, -5)
        pTopBackRight = adsk.core.Point3D.create(5, 5, -5)
        pBotBackLeft = adsk.core.Point3D.create(-5, -5, -5)
        pBotBackRight = adsk.core.Point3D.create(5, -5, -5)

        # top left, top right, bot left, bot right (order for nurbsurface creation!)
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopFrontLeft,
            pTopFrontRight,
            pBotFrontLeft,
            pBotFrontRight,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopFrontRight,
            pTopBackRight,
            pBotFrontRight,
            pBotBackRight,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopBackRight,
            pTopBackLeft,
            pBotBackRight,
            pBotBackLeft,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopBackLeft,
            pTopFrontLeft,
            pBotBackLeft,
            pBotFrontLeft,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopBackLeft,
            pTopBackRight,
            pTopFrontLeft,
            pTopFrontRight,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pBotFrontLeft,
            pBotFrontRight,
            pBotBackLeft,
            pBotBackRight,
        )

        ui.messageBox('lumps {}'.format(brepBodyDef.lumpDefinitions.count))

        body :adsk.fusion.BRepBody = brepBodyDef.createBody()
        ui.messageBox('brepBodyDef.outcomeInfo {}'.format(brepBodyDef.outcomeInfo))

        # Show the temporary brep bodies
        # group = rootComp.customGraphicsGroups.add()
        # group.addBRepBody(body)

        baseFeats = rootComp.features.baseFeatures
        baseFeat = baseFeats.add()
        baseFeat.startEdit()
        rootComp.bRepBodies.add(body, baseFeat)
        baseFeat.finishEdit()


    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

for example when cutting a cilinder from the generated cube:

Screenshot 2021-02-06 at 20.37.39.png

0 Likes
Accepted solutions (1)
633 Views
2 Replies
Replies (2)
Message 2 of 3

GRSnyder
Collaborator
Collaborator
Accepted solution

You are creating a separate lump and shell for every face, which means that you end up with 6 surfaces instead of one solid body.

 

If you created these in the UI, Fusion 360 would show them as six surface bodies rather than one. However, the modeling engine itself is fine with having multiple lumps per body. The "one lump per body" illusion is maintained by Fusion 360 checking the result of every UI operation and breaking up bodies as needed. But when you access the modeling engine directly, you need to do this part yourself. (Or in your case, where you only want one body, just put all the faces in one shell.)

Message 3 of 3

wh6Q9NU
Advocate
Advocate

@GRSnyder Thanks! Exactly the explenation I needed.

 

Updated example code for generating the cube

 

#Author-Codemans
#Description-Create cube, rib size 10

from typing import List, Dict, Tuple
import adsk.core, adsk.fusion, adsk.cam, traceback
# from . import utils as utils

def createShellAndFaceAndEdges(
    brepBodyDef :adsk.fusion.BRepBodyDefinition,
    pTopLeft :adsk.core.Point3D,
    pTopRight :adsk.core.Point3D,
    pBotLeft :adsk.core.Point3D,
    pBotRight :adsk.core.Point3D,
):
  if brepBodyDef.lumpDefinitions.count is 0:
    return

  # Create lump definition
  lumpDef = brepBodyDef.lumpDefinitions.item(0)

  if lumpDef.shellDefinitions.count is 0:
    return

  # Create shell definition
  shellDef = lumpDef.shellDefinitions.item(0)

  # Create face definition
  faceDef = shellDef.faceDefinitions.add(createFrontNurbsSurface(
      pTopLeft,
      pTopRight,
      pBotLeft,
      pBotRight,
  ), True)

  edges :List = createEdges(
      brepBodyDef,
      pTopLeft,
      pTopRight,
      pBotLeft,
      pBotRight,
  )

  # Create loop definition
  loopDef = faceDef.loopDefinitions.add()

  # Create coEdge definitions
  for edgeDef in edges:
      loopDef.bRepCoEdgeDefinitions.add(edgeDef, True)

def createEdge(
  brepBodyDef :adsk.fusion.BRepBodyDefinition,
  p0 :adsk.core.Point3D,
  p1 :adsk.core.Point3D,
) -> adsk.fusion.BRepCoEdgeDefinition:
  v0 :adsk.fusion.BRepVertexDefinition = brepBodyDef.createVertexDefinition(p0)
  v1 :adsk.fusion.BRepVertexDefinition = brepBodyDef.createVertexDefinition(p1)

  return brepBodyDef.createEdgeDefinitionByCurve(v0, v1, adsk.core.Line3D.create(p0, p1))

def createEdges(
  brepBodyDef :adsk.fusion.BRepBodyDefinition,
  pTopLeft :adsk.core.Point3D,
  pTopRight :adsk.core.Point3D,
  pBotLeft :adsk.core.Point3D,
  pBotRight :adsk.core.Point3D,
) -> List[adsk.fusion.BRepCoEdgeDefinition]:
  edges :List[adsk.fusion.BRepCoEdgeDefinition] = []

  edges.append(createEdge(brepBodyDef, pTopLeft, pBotLeft))
  edges.append(createEdge(brepBodyDef, pBotLeft, pBotRight))
  edges.append(createEdge(brepBodyDef, pBotRight, pTopRight))
  edges.append(createEdge(brepBodyDef, pTopRight, pTopLeft))

  return edges

def createFrontNurbsSurface(
  pTopLeft :adsk.core.Point3D,
  pTopRight :adsk.core.Point3D,
  pBotLeft :adsk.core.Point3D,
  pBotRight :adsk.core.Point3D,
) -> adsk.core.NurbsSurface:
    
    degreeU = 1
    degreeV = 1
    controlPointCountU = 2
    controlPointcountV = 2

    controlPoints = [pTopLeft, pTopRight, pBotLeft, pBotRight]

    knotsU = (0, 0, 1, 1)
    knotsV = (0, 0, 1, 1)
    weights = ()
    propertyU = 1
    propertyV = 1

    surface :adsk.core.NurbsSurface = adsk.core.NurbsSurface.create(
      degreeU,
      degreeV,
      controlPointCountU,
      controlPointcountV,
      controlPoints,
      knotsU,
      knotsV,
      weights,
      propertyU,
      propertyV,
    )

    return surface

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        # Create a new document
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        
        # Create a base feature
        rootComp = design.rootComponent

        brepBodyDef :adsk.fusion.BRepBodyDefinition = adsk.fusion.BRepBodyDefinition.create()

        # Create lump definition - one lump for the cube
        lumpDef = brepBodyDef.lumpDefinitions.add()

        # Create shell definition - one shell for the cube
        lumpDef.shellDefinitions.add()

        pTopFrontLeft = adsk.core.Point3D.create(-5, 5, 5)
        pTopFrontRight = adsk.core.Point3D.create(5, 5, 5)
        pBotFrontLeft = adsk.core.Point3D.create(-5, -5, 5)
        pBotFrontRight = adsk.core.Point3D.create(5, -5, 5)

        pTopBackLeft = adsk.core.Point3D.create(-5, 5, -5)
        pTopBackRight = adsk.core.Point3D.create(5, 5, -5)
        pBotBackLeft = adsk.core.Point3D.create(-5, -5, -5)
        pBotBackRight = adsk.core.Point3D.create(5, -5, -5)

        # 6 faces of the cube
        # params are: top left, top right, bot left, bot right (order for nurbsurface creation)
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopFrontLeft,
            pTopFrontRight,
            pBotFrontLeft,
            pBotFrontRight,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopFrontRight,
            pTopBackRight,
            pBotFrontRight,
            pBotBackRight,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopBackRight,
            pTopBackLeft,
            pBotBackRight,
            pBotBackLeft,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopBackLeft,
            pTopFrontLeft,
            pBotBackLeft,
            pBotFrontLeft,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pTopBackLeft,
            pTopBackRight,
            pTopFrontLeft,
            pTopFrontRight,
        )
        createShellAndFaceAndEdges(
            brepBodyDef,
            pBotFrontLeft,
            pBotFrontRight,
            pBotBackLeft,
            pBotBackRight,
        )

        ui.messageBox('lumps {}'.format(brepBodyDef.lumpDefinitions.count))

        body :adsk.fusion.BRepBody = brepBodyDef.createBody()
        ui.messageBox('brepBodyDef.outcomeInfo {}'.format(brepBodyDef.outcomeInfo))

        # Show the temporary brep bodies
        # group = rootComp.customGraphicsGroups.add()
        # group.addBRepBody(body)

        baseFeats = rootComp.features.baseFeatures
        baseFeat = baseFeats.add()
        baseFeat.startEdit()
        rootComp.bRepBodies.add(body, baseFeat)
        baseFeat.finishEdit()


    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

B-Rep and Geometry documentation: 

http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1C3FFADB-52C4-49BB-8981-4A448FFE4442

 

And now subtracting a cilinder returns the expected result.

Screenshot 2021-02-07 at 15.13.38.png

0 Likes