3 Replies Latest reply on Sep 27, 2016 7:00 AM by Brad Phelan

    How to return a wire body from a macro feature

    Johannes Kronberger

      As a test I wish to build a wire body from a selected sketch in my macro feature.

       

      I have the below code in my macro feature rebuild method. I select a sketch with only a single open contour in it and then build the wire body. However Solidworks always errors out and says that I need to check my geometry and/or tracking ids. Is there anything obviously wrong below?

       

                  var cookies = SwApp.RegisterTrackingDefinition("Tracking_API");

                  if (cookies == -1)

                      return null; // No cookies found.

                  var a = SwFeatureData.GetSelectedObjects(

                      (type, mark) =>

                          (type == swSelectType_e.swSelSKETCHES && mark == (int) SelectionMarksEnum.ProjectionCurve))

                      .FirstOrDefault();

                  var projectionCurveSketch = GetSketch(a);

       

                  var b = SwFeatureData.GetSelectedObjects(

                      (type, mark) =>

                          (type == swSelectType_e.swSelSKETCHES && mark == (int) SelectionMarksEnum.DepthCurve))

                      .FirstOrDefault();

                  var depthCurveSketch = GetSketch(b);

       

       

                  Debug.Assert(depthCurveSketch != null, "depthCurveSketch != null");

       

       

                  var xform = depthCurveSketch.ModelToSketchXform;

                  var edgesO = (object[]) depthCurveSketch.GetContourEdges(xform);

                  var edges = edgesO.Select(o => (IEdge) o).ToArray();

                  var curves= edges.Select(edge => (ICurve) edge.GetCurve())

                      .Select(c=>(ICurve)c.Copy())

                      .ToArray();

                  var wireBody = modeler.CreateWireBody(curves , (int)swCreateWireBodyOptions_e.swCreateWireBodyByDefault);

                  wireBody.SetTrackingID(cookies, 12);

                  return wireBody;

       

      with helper methods

       

              private static ISketch GetSketch(object a)

              {

                  return (ISketch)((IFeature) a)?.GetSpecificFeature2();

              }

       

      and

       

              public static IEnumerable<object> GetSelectedObjects(this IMacroFeatureData selMgr, Func<swSelectType_e, int, bool> filter)

              {

                  {

                      object objects;

                      object objectTypes;

                      object marks;

                      object drViews;

                      object componentXForms;

                      selMgr.GetSelections3(out objects, out objectTypes, out marks, out drViews, out componentXForms);

       

                      var objectsArray = (object[])objects;

                      var typesArray = (swSelectType_e[])objectTypes;

                      var marksArray = (int[])marks;

                      var i = 0;

                      foreach (var item in objectsArray)

                      {

                          if(filter(typesArray[i], marksArray[i]))

                          {

                              yield return item;

                          }

                          i++;

                      }

                  }

              }

        • Re: How to return a wire body from a macro feature
          Artem Taturevych

          Try to assign the ids to your curve edges:

           

          IMacroFeatureData::GetEntitiesNeedUserId

          IMacroFeatureData::SetEdgeUserId.

           

          It is demonstrated in this example: 2015 SOLIDWORKS API Help - Cut Body in Half using Macro Feature Example (VBA)

           

          Thanks,
          Artem

            • Re: How to return a wire body from a macro feature
              Johannes Kronberger

              I added in

               

                          {

                              object facesNeedId;

                              object EdgesNeedId;

                              SwFeatureData.GetEntitiesNeedUserId(wireBody, out facesNeedId, out EdgesNeedId);

                              var edgesNeedId = (object[]) EdgesNeedId;

                              int i = 0;

                              foreach (var edge in edgesNeedId)

                              {

                                  SwFeatureData.SetEdgeUserId((Edge)edge, i, 0);

                                  i++;

                              }

               

               

                          }

               

              and removed the old code for tracking ids and it just work. Tracking id's are kind of voodoo to me

                • Re: How to return a wire body from a macro feature
                  Brad Phelan

                  This no longer works if I return two wire bodies in an array. The wire bodies display on the screen but when I try to reference a vertex, on the next rebuild Solidworks can't find the vertex reference.

                   

                  I even tried the following.

                   

                    var cookies = SwApp.RegisterTrackingDefinition("Tracking_API");

                              if (cookies == -1)

                              {

                                  throw new Exception("Cookies are invalid");

                              }

                   

                                       wireBody.SetTrackingID(cookies, i ++);

                   

                   

                                       wireBody

                                           .GetVertices()

                                           .CastArray<IVertex>()

                                           .ForEach(v=>

                                                    {

                                                        var err = v.SetTrackingID(cookies, i++);

                                                        if (err != 0)

                                                            throw new Exception($"SetTracking ID failed with {(swTrackingIDError_e) err}");

                                                    });

                   

                   

                                       wireBody

                                          .GetEdges()

                                          .CastArray<IEdge>()

                                          .ForEach(v=>

                                                   {

                                                       var err = v.SetTrackingID(cookies, i++);

                                                       if (err != 0)

                                                           throw new Exception($"SetTracking ID failed with {(swTrackingIDError_e) err}");

                                                   });

                                                   */