How can we create a vertex on a face belong to a cylinder?

Erik Kostson
Erik Kostson Member, Employee Posts: 202
50 Answers 100 Comments Photogenic 5 Likes
✭✭✭✭
edited May 15 in 3D Design

Say we have a cylindrical body, how can we then create a vertex on each of the 2 capping/end faces (so at the top and bottom)?

Best Answers

  • Erik Kostson
    Erik Kostson Member, Employee Posts: 202
    50 Answers 100 Comments Photogenic 5 Likes
    ✭✭✭✭
    edited May 9 Answer ✓

    Below is one of many possible ways of doing this (works with API.V23.2)- the reference test example below, assumes there is at least one cylindrical body with 2 planar capping/end faces and one cylindrical face.

    assembly = GetRootPart() 
    bodies=assembly.Bodies
    mybodies=[]
    cx=[]
    cy=[]
    cz=[]
    for body in bodies:
        faces=body.Faces
        nrfaces=len(faces)
        if body.GetMaster().Shape.IsClosed==True and nrfaces==3: # check it is a solid body and cylindrical consist of 3 faces
            mybodies.append(body)
            for face in faces: # splits face in half
                if str(face.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Plane": 
                    edges=face.Edges
                    a=MeasureHelper.GetCentroid(Selection.Create(face)) # gets centroid (can be used to get vertex)
                    cx.append(a[0])
                    cy.append(a[1])
                    cz.append(a[2])
                    for edge in edges:
                        options = SplitFaceOptions()
                        fselection = FaceSelection.Create(face)
                        point = EdgeSelection.Create(edge).Items[0].EvalProportion(0.5).Point
                        result = SplitFace.ByParametric(fselection, point, FaceSplitType.Perpendicular, options)
                        f=(body.Faces[nrfaces])
                        nwedges=f.Edges
                        nredges=len(nwedges)
                        for nedge in nwedges: # splits new line edge in half -> vertex is created
                            if str(nedge.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Line": # gets the staigt edge on the half circular face
                                selections = EdgeSelection.Create(nedge)
                                end=nedge.Shape.EndPoint
                                result = SplitEdge.ByCount(selections,2)
    
  • Erik Kostson
    Erik Kostson Member, Employee Posts: 202
    50 Answers 100 Comments Photogenic 5 Likes
    ✭✭✭✭
    edited May 9 Answer ✓

    The above can be adapted to loop through a named selection containing planar faces (e.g., capping plane/face of a cylinder). These faces will be split in half and a vertex will be finally created at the centroid of the face. The centroid values of the face are also stored (cx,cy,cz) in case they would need to be used.

    groups = GetActiveWindow().ActiveWindow.Groups
    cx=[]
    cy=[]
    cz=[]
    
    for ns in groups:
        me=ns.Members
        for mem in me:
            if str(mem.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Plane": ## can be changed say to "SpaceClaim.Api.V232.Geometry.Cone"
                edge=mem.Edges[0]
                a=MeasureHelper.GetCentroid(Selection.Create(mem))
                cx.append(a[0])
                cy.append(a[1])
                cz.append(a[2])
                options = SplitFaceOptions()
                fselection = FaceSelection.Create(mem)
                point = EdgeSelection.Create(edge).Items[0].EvalProportion(0.5).Point
                result = SplitFace.ByParametric(fselection, point, FaceSplitType.Perpendicular, options)
    
    nme=ns.Members
    for i in range(0,len(nme),2):
        nwedges=nme[i].Edges
        for nedge in nwedges:
            if str(nedge.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Line":
                selections = EdgeSelection.Create(nedge)
                end=nedge.Shape.EndPoint
                result = SplitEdge.ByCount(selections,2)
    
    
  • Erik Kostson
    Erik Kostson Member, Employee Posts: 202
    50 Answers 100 Comments Photogenic 5 Likes
    ✭✭✭✭
    Answer ✓

    In addition to the above code, we can add this to create groups from the vertices generated at the centre of the face (so add the below code to the above script):

    import math
    ​​​​​​​myv=[]
    myvIds=[]
    dist=1E12
    nme=ns.Members # create named selection
    for j in range(0,len(cx)):
        for i in range(0,len(nme),2):
            nwedges=nme[i].Edges
            for nedge in nwedges:
                 if str(nedge.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Line":
                     ep=nedge.GetChildren[CurvePoint]()
                     for e in ep:
                        ex=e.Position[0]
                        ey=e.Position[1]
                        ez=e.Position[2]
                        dists=math.sqrt((float(cx[j])-ex)**2+(float(cy[j])-ey)**2+(float(cz[j])-ez)**2)
                        if dists<dist:
                            myvs=(e)
                            dist=dists
        primarySelection = Selection.Create(myvs)
        secondarySelection = Selection.Empty()
        result = NamedSelection.Create(primarySelection, secondarySelection) 
        dist=1E12
        myv.append(myvs)
    
  • Erik Kostson
    Erik Kostson Member, Employee Posts: 202
    50 Answers 100 Comments Photogenic 5 Likes
    ✭✭✭✭
    edited May 14 Answer ✓

    Finally the below script adds all the 3 scripts above together. In summary it gets the first named selection/group containing planar faces (e.g., capping plane/face of a cylinder). These faces will be split in half and a vertex will be finally created at the centroid of the face. The centroid values of the face are also stored (cx,cy,cz) as they are used in the end to get the vertex closest to them (generating one group for each vertex).

    import math
    group = GetActiveWindow().ActiveWindow.Groups[0]
    cx=[]
    cy=[]
    cz=[]
    myv=[]
    myvIds=[]
    dist=1E12
    
    me=group.Members
    for mem in me:
        if str(mem.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Plane": ## can be changed say to "SpaceClaim.Api.V232.Geometry.Cone"
            edge=mem.Edges[0]
            a=MeasureHelper.GetCentroid(Selection.Create(mem))
            cx.append(a[0])
            cy.append(a[1])
            cz.append(a[2])
            options = SplitFaceOptions()
            fselection = FaceSelection.Create(mem)
            point = EdgeSelection.Create(edge).Items[0].EvalProportion(0.5).Point
            result = SplitFace.ByParametric(fselection, point, FaceSplitType.Perpendicular, options)
    
    group = GetActiveWindow().ActiveWindow.Groups[0]
    nme=group.Members # generate centre vertex / split line in half
    for i in range(0,len(nme),2):
        nwedges=nme[i].Edges
        for nedge in nwedges:
            if str(nedge.Shape.Geometry.GetType())=='SpaceClaim.Api.V232.Geometry.Line':
                selections = EdgeSelection.Create(nedge)
                end=nedge.Shape.EndPoint
                result = SplitEdge.ByCount(selections,2)
    
    group = GetActiveWindow().ActiveWindow.Groups[0]
    nmes=group.Members # generate group of centre vertex
    for j in range(0,len(cx)):
        for i in range(0,len(nmes),2):
            nwedges=nmes[i].Edges
            for nedge in nwedges:
                 if str(nedge.Shape.Geometry.GetType())=="SpaceClaim.Api.V232.Geometry.Line":
                     ep=nedge.GetChildren[CurvePoint]()
                     for e in ep:
                        ex=e.Position[0]
                        ey=e.Position[1]
                        ez=e.Position[2]
                        dists=math.sqrt((float(cx[j])-ex)**2+(float(cy[j])-ey)**2+(float(cz[j])-ez)**2)
                        if dists<dist:
                            myvs=(e)
                            dist=dists
        primarySelection = Selection.Create(myvs)
        secondarySelection = Selection.Empty()
        result = NamedSelection.Create(primarySelection, secondarySelection) 
        dist=1E12
        myv.append(myvs)
    
This discussion has been closed.