8 Replies Latest reply on Nov 2, 2012 4:01 PM by Jacob Corder

    API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.

    Jacob Corder

      I have a feature that i am programatically creating from a database. it starts with a simple legacy hole from the hole wizard. I delete all Sketch lines from the profile sketch and create my own profile with my code.

       

      I basically have a stepped hole with multiple diameters and depths. see the Cavity With Intersections.bmp file attached.

       

      My next step is to define enterance points into this feature. if i can utilize faces that are inline with eachother for example split the face into 3 sections giving me the ability to verify that only the specific face can be affected by other features,  then i could use that for verification that my intersections exist and that they are correct.

       

      See Cavity with Ports.bmp attached

       

      More information. The locations and hole diameters that can intersect this feature are defined. i cannot add a larger hole into this feature than what is allowed. i also need a hole to intersect for another portion of my program to work, its a verification that all tasks are completed correctly. This feature i am programming is for defining fluid flow paths inside of a solid block of a material (metal, plastic, ect. not relevant)

       

      I have tried ISplitFaceOnParam2, ISplitFaceOnParamCount2, and SplitFaceOnParam.

       

      i do not have sample code that would help here. I am just looking for the correct direction to split a cylindrical face into 3 specific sections with the API.

       

      Thanks for your help in advance.

        • Re: API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.
          Artem Taturevych

          Excuse me if I miss your point but as far as I understand you need to split your face into a pieces so faces could be selected separately for some analysis.

           

          Like in the following picture. Cylinder to the left is original one and to the right is what you are looking for.

           

          split.png

           

          If that's true you cannot actually use Modeler::SplitFaceOnParam. It is doing exactly what you need but it is creating new temporary faces which should be converted to temporary bodies but not affects original faces.

           

          You may probably use the Insert->Curve->Split Line... and use projected. The API antilog is ModelDoc2::InsertSplitLineProject.

           

          Hope it helps.

          ______________________

          Regards,

          Artem Taturevych

          Application Engineer at Intercad

          http://intercad.com.au/

          Tel: +61 2 9454 4444

            • Re: API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.
              Rajat Jain

              Artem,

               

              I just created a split on a cylindrical face by using Modeler::SplitFaceOnParam, saved the model and closed. Reopened the model and the split was there. It seems that the generated faces are not temporary.

               

              I am sure Modeler::SplitFaceOnParam is the API which can be well used here. Another advantage is that it does not create any additional feature in the FeatureManager.

               

              Hope it helps!!!

               

              Rajat Jain

               

              Jacob: It seems that you are developing a Manifold Design Addin on SolidWorks. If its true then you can mail me directly at rajatjain.iitd[at]gmail.com and I can support you with some resources.

                • Re: API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.
                  Artem Taturevych

                  Thanks, Rajat, you are correct - it's my fault. I thought about other method (if I'm not mistaken the Surface::MakeIsoCurves ) which splits the face by curves. I've used this method before for preview purposes and remember that it is for temporarily geometry. Good catch!

                  • Re: API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.
                    Jacob Corder

                    Thanks for The fast responses. 

                       

                    Here is my code that i am trying to get to work. any numbers in the following code were replaced with values for debugging purposes. my actual values are in a sql server that is queried for my required data.

                     

                    the first time i run SplitFaceCount i recieve a return of 0, the second time it runs ill recieve an additional face, after the function ends the additional face disappears. now i dont quite know how the program is supposed to pass the parameter values.

                     

                    Is it from the xyz origin or relative to the face?

                     

                                                        SplitFaces = swModeler.ISplitFaceOnParam2

                                                        SplitFaceCount = swModeler.ISplitFaceOnParamCount2(FeatFaces(FF), swSplitFaceOnParam_e.swSplitFaceOnParamU, ((EntPoint + SFDepth) - (0.1 / 2) * InchesToMeters), SplitStatus)

                                                        SplitFaceCount = SplitFaceCount + swModeler.ISplitFaceOnParamCount2(FeatFaces(FF), swSplitFaceOnParam_e.swSplitFaceOnParamU, ((EntPoint + SFDepth) - (0.1 / 2) * InchesToMeters), SplitStatus)

                                                        SplitFaceCount = SplitFaceCount + swModeler.ISplitFaceOnParamCount2(FeatFaces(FF), swSplitFaceOnParam_e.swSplitFaceOnParamU, ((EntPoint + SFDepth) + (0.1 / 2) * InchesToMeters), SplitStatus)

                                                        SplitFaces(i) = swModeler.ISplitFaceOnParam2

                     

                     

                                                        '

                                                        SecondSplitFaces = swModeler.ISplitFaceOnParam2

                                                        SplitFaceCount2 = swModeler.ISplitFaceOnParamCount2(FeatFaces(FF), swSplitFaceOnParam_e.swSplitFaceOnParamV, ((EntPoint + SFDepth) - (0.1 / 2) * InchesToMeters), SplitStatus)

                                                        SplitFaceCount2 = SplitFaceCount2 + swModeler.ISplitFaceOnParamCount2(FeatFaces(FF), swSplitFaceOnParam_e.swSplitFaceOnParamV, ((EntPoint + SFDepth) - (0.1 / 2) * InchesToMeters), SplitStatus)

                                                        SplitFaceCount2 = SplitFaceCount2 + swModeler.ISplitFaceOnParamCount2(FeatFaces(FF), swSplitFaceOnParam_e.swSplitFaceOnParamV, ((EntPoint + SFDepth) + (0.1 / 2) * InchesToMeters), SplitStatus)

                                                        SecondSplitFaces(i) = swModeler.ISplitFaceOnParam2

                • Re: API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.
                  Jacob Corder

                  Here are my findings with the help of Rajat Jain, and Artem Taturevych.

                   

                  When Splitting Faces you can either use ISplitFaceOnParamCount2 and get the new face with iSplitFaceOnParam2 which will thet the newly split faces that ISplitFaceOnParamCount2 created, or use SplitFaceOnParam.

                   

                  One thing to note is that when a rebuild happens all of the faces will then blend into one face again. I Am adding the split face function to my Macro Feature (COMFeature) to recreate these faces upon rebuild. I will be chaning this to delete the center face of the 3 and add a surface in its place.

                   

                  Very IMPORTANT TO KNOW and thanks to Rajat Jain i was able to make this work.  When splitting the face you must Check that the face and surface are sensed in the same direction. This was one of my biggest hiccups, I Then applied the UV Parameters of the face to my modify the face code to ensure that the face was split correctly. 

                   

                  ANOTHER VERY IMPORTANT THING TO KNOW.  Make sure you make the beggining face a safe entity so you can go back to it for any additional Face Splits. If you dont then the first split face modifies the second split faces location and it is hard to capture which face was split because the first split causes 2 faces but which face is the new one? This was also a great suggestion by Rajat Jain.

                   

                  Also getting the UV bounds is required because this gives you the UV parameters of the face to which the split must apply. For example if you have a face that is 1" deep and you want to split it at .5" and .25" it is not always safe to assume that the axis which is recieved from the UV parameters starts at the beginning point of your feature (The features Face that it was created on). also they might be going in the opposite direction so the split must take this into account. 

                   

                   

                  SPLITTING A FACE OF A CYLINDER REQUIRES  the swSplitFaceOnParam_e Argument to be swSplitFaceOnParam_e.swSplitFaceOnParamV  not U

                   

                  NOTE:::::: When rebuilt this will eliminate any newly created Faces. So i have set to delete the face that i want to be the center face. I ran a check to get the UV params and if my target dimension lied within the Upper and lower V parameters i delete it.

                   

                  Here is the Code that i got to work.

                      Public Function SplitFaceInto3Sections(ByVal FeatureWithFaces As Feature) As Boolean

                     

                          Try

                              Dim ModView As ModelView

                              If ModDoc Is Nothing Then ModDoc = iswapp.ActiveDoc

                              If SelMgr Is Nothing Then SelMgr = ModDoc.SelectionManager

                              Dim SelData As SelectData = SelMgr.CreateSelectData

                              ModDoc.ForceRebuild3(True)

                              ModView = ModDoc.ActiveView

                              Dim RectArray(3) As Double

                              Dim boolstatus As Boolean

                              Dim SFDepth As Double = CDbl(Trim(SFDepthTB.Text))

                              Dim FaceCount As Integer = ModifyHole.GetFaceCount()

                              If FaceCount = Nothing Or FaceCount = 0 Then Return False

                              Dim FeatFaces(FaceCount - 1) As Face2

                              Dim FaceObj As Object = ModifyHole.GetFaces

                              For i = 0 To FaceCount - 1

                                  FeatFaces(i) = FaceObj(i)

                              Next

                              Dim ThisSurface As Surface

                              Dim SurfaceParams As Object

                              Dim TheseParams(6) As Object

                              Dim SurfaceRadius As Double = Nothing

                              Dim SurfDepth As Double = Nothing

                              Dim ThisRow As DataRow

                              Dim SurfDiameter As Double = Nothing

                              Dim swModeler As Modeler = iswapp.GetModeler

                              Dim EntDiameter As Double = Nothing

                              Dim EntPoint As Double = Nothing

                              Dim SplitStatus As Boolean

                              Dim SplitFaces(2) As Face2

                              Dim SplitSurfaces(2) As Surface

                              Dim SecondSplitFaces As Object = Nothing

                              Dim SplitFaceName(1, 1) As String

                              Dim IntersectionFace As Object = Nothing

                              Dim MinDiam As Double

                              Dim MaxDiam As Double

                              Dim CompareDiam As Double

                              Dim SplitFaceCount As Integer

                              Dim SplitFaceCount2 As Integer

                              Dim FaceStart As Double

                              Dim TopSplit As Double

                              Dim BottomSplit As Double

                              Dim MatValues(8) As Double

                              Dim UVBounds As Object

                              Dim MinUParam As Double

                              Dim MaxUParam As Double

                              Dim MinVParam As Double

                              Dim MaxVParam As Double

                              Dim FaceInSurfOpposite As Boolean

                              Dim BeforeFaceCount As Integer = ModifyHole.GetFaceCount

                              Dim FaceToSplit As Entity

                              Dim SafeFaceToSplit As Entity

                              Dim SurfParam As SurfaceParameterizationData

                              Dim FaceSelectedCount As Integer

                              Dim TheseUVBounds As Object

                              Dim EntPointToBottomEdge As Double

                              MatValues(0) = 255

                              MatValues(1) = 0

                              MatValues(2) = 0

                              MatValues(3) = 0

                              MatValues(4) = 0

                              MatValues(5) = 0

                              MatValues(6) = 0

                              MatValues(7) = 0

                              MatValues(8) = 0

                              Dim IntValues(8) As Double

                              IntValues(0) = 0

                              IntValues(1) = 255

                              IntValues(2) = 0

                              IntValues(3) = 0

                              IntValues(4) = 0

                              IntValues(5) = 0

                              IntValues(6) = 0

                              IntValues(7) = 0

                              IntValues(8) = 0

                              Dim FaceUVBounds(2, 6) As Double

                              For FF = 0 To FaceCount - 1

                                  ThisSurface = FeatFaces(FF).GetSurface

                                  Debug.Print("Surface is Revolved = " & ThisSurface.IsRevolved)

                                  If ThisSurface.IsCylinder = True Then

                                      SurfaceParams = ThisSurface.CylinderParams

                                      For i = 0 To 6

                                          TheseParams(i) = SurfaceParams(i) / InchesToMeters

                                      Next

                   

                   

                                      For i = 0 To FeatureSpecsDataTable.Rows.Count - 1

                                          If Not SelMgr.GetSelectedObjectCount2(-1) = 0 Then ModDoc.ClearSelection2(True)

                                          ThisRow = FeatureSpecsDataTable.Rows(i)

                                          MinDiam = ThisRow("MinDiameter")

                                          MaxDiam = ThisRow("MaxDiameter")

                                          CompareDiam = Math.Round((TheseParams(6) * 2), 4)

                                          EntDiameter = ThisRow("EntDiameter")

                                          EntPoint = ThisRow("EntPoint")

                                          SurfDepth = ThisRow("Depth")

                                          SurfDiameter = ThisRow("MinDiameter")

                                          If Not EntPoint >= SurfDepth Then

                                              If Not EntDiameter = 0 And Not EntPoint = 0 Then

                                                  If MinDiam <= CompareDiam And MaxDiam >= CompareDiam Then

                                                      FaceToSplit = Nothing

                                                      SafeFaceToSplit = Nothing

                                                      FaceToSplit = FeatFaces(FF)

                                                      SafeFaceToSplit = FaceToSplit.GetSafeEntity()

                                                      SurfParam = ThisSurface.Parameterization2()

                                                      UVBounds = FeatFaces(FF).GetUVBounds

                                                      MinUParam = CDbl(UVBounds(0))

                                                      MaxUParam = CDbl(UVBounds(1))

                                                      MinVParam = CDbl(UVBounds(2))

                                                      MaxVParam = CDbl(UVBounds(3))

                                                      FaceInSurfOpposite = FeatFaces(FF).FaceInSurfaceSense

                   

                   

                                                      If MinVParam > MaxVParam Then 'Minvparam + (depth - entrancepoint) - 1/2 ent diam

                                                          TopSplit = Math.Round((MinVParam / InchesToMeters), 4) + ((SurfDepth - EntPoint) - (EntDiameter / 2))

                                                          BottomSplit = Math.Round((MinVParam / InchesToMeters), 4) + ((SurfDepth - EntPoint) + (EntDiameter / 2))

                                                      ElseIf MinVParam < MaxVParam Then 'Maxvparam + (depth - entrancepoint)

                                                          BottomSplit = Math.Round((MaxVParam / InchesToMeters), 4) - ((SurfDepth - EntPoint) - (EntDiameter / 2))

                                                          TopSplit = Math.Round((MaxVParam / InchesToMeters), 4) - ((SurfDepth - EntPoint) + (EntDiameter / 2))

                                                      ElseIf MinVParam = MaxVParam Then

                                                          AddIntersections = False

                                                          Exit Function

                                                      Else

                   

                   

                                                      End If

                   

                   

                                                      SplitFaces(0) = FeatFaces(FF)

                                                      If Not SplitFaces(0) Is Nothing Then SplitFaces(0).SetMaterialPropertyValues2(MatValues, swInConfigurationOpts_e.swAllConfiguration, ModDoc.GetConfigurationNames)

                                                      SplitFaceCount = swModeler.ISplitFaceOnParamCount2(SafeFaceToSplit, swSplitFaceOnParam_e.swSplitFaceOnParamV, (TopSplit * InchesToMeters), SplitStatus)

                                                      SplitFaces(1) = swModeler.ISplitFaceOnParam2

                                                      If Not SplitFaces(1) Is Nothing Then SplitFaces(1).SetMaterialPropertyValues2(MatValues, swInConfigurationOpts_e.swAllConfiguration, ModDoc.GetConfigurationNames)

                                                      SplitFaceCount2 = swModeler.ISplitFaceOnParamCount2(SafeFaceToSplit, swSplitFaceOnParam_e.swSplitFaceOnParamV, (BottomSplit * InchesToMeters), SplitStatus)

                                                      SplitFaces(2) = swModeler.ISplitFaceOnParam2

                                                      If Not SplitFaces(2) Is Nothing Then SplitFaces(2).SetMaterialPropertyValues2(IntValues, swInConfigurationOpts_e.swAllConfiguration, ModDoc.GetConfigurationNames)

                   

                   

                                                      For stf = 0 To 2 Step 1

                                                          EntPointToBottomEdge = (EntPoint * InchesToMeters)

                                                          If Not SplitFaces(stf) Is Nothing Then

                                                              TheseUVBounds = SplitFaces(stf).GetUVBounds()

                                                              If Math.Abs(TheseUVBounds(2)) > EntPointToBottomEdge And Math.Abs(TheseUVBounds(3)) < EntPointToBottomEdge Then

                                                                  ModDoc.ClearSelection2(True)

                                                                  boolstatus = SelMgr.AddSelectionListObject(SplitFaces(stf), SelData)

                                                                  If SelMgr.GetSelectedObjectCount2(-1) = 1 Then boolstatus = ModDoc.Extension.InsertDeleteFace(swFaceDeleteOption_e.swFaceDelete_Default)

                                                                  Debug.Print("Face Deleted = " & boolstatus)

                                                              ElseIf Math.Abs(TheseUVBounds(2)) < EntPointToBottomEdge And Math.Abs(TheseUVBounds(3)) > EntPointToBottomEdge Then

                                                                  ModDoc.ClearSelection2(True)

                                                                  boolstatus = SelMgr.AddSelectionListObject(SplitFaces(stf), SelData)

                                                                  If SelMgr.GetSelectedObjectCount2(-1) = 1 Then boolstatus = ModDoc.Extension.InsertDeleteFace(swFaceDeleteOption_e.swFaceDelete_Default)

                                                                  Debug.Print("Face Deleted = " & boolstatus)

                   

                   

                                                              End If

                                                              For UVB = 0 To 3

                                                                  FaceUVBounds(stf, UVB) = TheseUVBounds(UVB)

                                                              Next

                                                          End If

                                                      Next stf

                                                      ModView.GraphicsRedraw(RectArray)

                                                      FaceSelectedCount = SelMgr.AddSelectionListObjects(SplitFaces, SelData)

                                                      If FaceSelectedCount = 0 Then SelMgr.AddSelectionListObjects(SplitSurfaces, SelData)

                                                      If FaceSelectedCount > 0 Then

                                                          ModDoc.InsertFeatureReplaceFace()

                                                          Debug.Print("Face Split = " & SplitStatus)

                                                      End If

                                                      ModDoc.InsertFeatureReplaceFace()

                                                      Debug.Print("Face Split = " & SplitStatus)

                                                  End If

                                              End If

                                          End If

                                      Next

                                  End If

                              Next

                         Catch ex As Exception

                              iswapp.SendMsgToUser2(ex.Message, swMessageBoxIcon_e.swMbWarning, swMessageBoxBtn_e.swMbOk)

                       Finally

                       End Try

                  End Function

                  • Re: API Guidance Needed to Split Cylindrical Faces into 3 Sections, All Faces Must be the Same Diameter but Separate Entities.
                    Jacob Corder

                    I Have come across some additional Data.  If you are to Use this in conjunction with a macro feature, make the macro feature regenerate function create these split faces, They will not ever become temporary. See below i have created the split faces along with the second image having them all selected. Works very well. Feel free to ask any questions about this.

                    Cavity With Intersections Complete.bmpCavity Intersections Selected.bmp