Creation of Swept Geometry

Creation of Swept Geometry

islam.alqalyubi
Participant Participant
934 Views
5 Replies
Message 1 of 6

Creation of Swept Geometry

islam.alqalyubi
Participant
Participant

I am writing a method that takes a Sweep object and returns Solid (Swept Geometry) the purpose of this method may appear to be weired but I am doing this as a work around to get a valid solid geometry in case of sweep void in order to perform BooleanOperationUtils.ExecuteBooleanOperation. but I got this exception 
"Autodesk.Revit.Exceptions.ArgumentException: 'The given attachment point don't lie in the plane of the Curve Loop.
Parameter name: pathAttachmentCrvIdx & pathAttachmentParam'"

Here is the code snippet

the exception is thrown on line 22

// main method
public static Solid GetVoidSweepSolid(Sweep ownerElement)
{
  Solid voidSolid = null;
  CurveLoop pathCurveLoop=null;
  List<CurveLoop> pathProfile = [];
  var pathCurves = GetCurveArrArrCurves(ownerElement.Path3d.AllCurveLoops).FirstOrDefault();
  var endPoints = pathCurves.Select(c => (c.GetEndPoint(0), c.GetEndPoint(1))).ToList();
  if (pathCurves != null)
  {
    pathCurveLoop = ConvertToCurveLoop(pathCurves);
  }

  var profileCurves = GetCurveArrArrCurves(ownerElement.ProfileSketch.Profile);
  foreach (var curves in profileCurves)
  {
    pathProfile.Add(ConvertToCurveLoop(curves));
  }

  if (pathCurveLoop != null && pathProfile.Any())
  {
    voidSolid = GeometryCreationUtilities.CreateSweptGeometry(pathCurveLoop, 0, pathCurves[0].GetEndParameter(0), pathProfile);
  }
  return voidSolid;
}

// helper methods
public static List<List<Curve>> GetCurveArrArrCurves(CurveArrArray curveArrArr)
{
  List<List<Curve>> curves = [];
  var iter = curveArrArr.ForwardIterator();
  while (iter.MoveNext())
  {
    List<Curve> arrCurves = [];
    if (iter.Current is CurveArray curveArr)
    {
      var iter2 = curveArr.ForwardIterator();
      while (iter2.MoveNext())
      {
        if (iter2.Current is Curve curve)
        {
          arrCurves.Add(curve);
        }
      }
    }
    if (arrCurves.Any()) curves.Add(arrCurves);
  }
  return curves;
}

public static CurveLoop ConvertToCurveLoop(IEnumerable<Curve> curves)
{
  CurveLoop loop = null;
  if (curves?.Any() == true)
  {
    loop = new CurveLoop();
    foreach (var curve in curves)
      loop.Append(curve);
  }
  return loop;
}

 

0 Likes
Accepted solutions (1)
935 Views
5 Replies
Replies (5)
Message 2 of 6

RPTHOMAS108
Mentor
Mentor

In original sweep is profile attached at mid-point of first curve in path, not one of the end parameters of such?

 

To get the true reflection you would want to attach the profile in the same location it is in original sweep otherwise loops that form profile may not be at right orientation to suit the point at which they are attached in new element.

 

 

0 Likes
Message 3 of 6

islam.alqalyubi
Participant
Participant

How can I know the real location of profile relative to the path?

0 Likes
Message 4 of 6

islam.alqalyubi
Participant
Participant

I have added a method that calculates the location of the sweep profile relative to the sweep path, as shown between lines 18, and 29, but still get the same exception.

public static Solid GetVoidSweepSolid(Sweep ownerElement)
{
  Solid voidSolid = null;
  CurveLoop pathCurveLoop=null;
  List<CurveLoop> pathProfile = [];
  var pathCurves = GetCurveArrArrCurves(ownerElement.Path3d.AllCurveLoops).FirstOrDefault();
  if (pathCurves != null)
  {
    pathCurveLoop = ConvertToCurveLoop(pathCurves);
  }

  var profileCurves = GetCurveArrArrCurves(ownerElement.ProfileSketch.Profile);
  foreach (var curves in profileCurves)
  {
    pathProfile.Add(ConvertToCurveLoop(curves));
  }

  var profileOrigin = ownerElement.ProfileSketch.SketchPlane.GetPlane().Origin;
  int pathCrvIdx = 0;
  double pathAttachParam = 0.0;
  foreach (var curve in pathCurves)
  {
    if(IsPointOnCurve(profileOrigin, curve))
    {
      pathCrvIdx = pathCurves.IndexOf(curve);
      pathAttachParam = GetPointParameter(profileOrigin, curve);
      break;
    }
  }

  if (pathCurveLoop != null && pathProfile.Any())
  {
    voidSolid = GeometryCreationUtilities.CreateSweptGeometry(pathCurveLoop, pathCrvIdx, pathAttachParam, pathProfile);
  }
  return voidSolid;
}

 

0 Likes
Message 5 of 6

RPTHOMAS108
Mentor
Mentor

The raw parameter of curve mid point is often the average of the two ends there is also Curve.ComputeRawParameter however it can become slightly more complicated than this:

 

When you create a sweep path with multiple curves it puts the profile on midpoint of first curve you create. However I believe there is no easy way to find that later for your purpose, but that doesn't matter.

 

Often the easiest thing to do is construct the profile on the XY plane and transform it to where it needs to be using a transform built from normalised vectors of Curve.ComputeDerivatives or alternatively where this can't be used (line) you can establish the system via line direction, right direction and the cross product of such.

In source family environment the sweep path is bound to a plane so for curves that don't have an inherent right direction (lines) you can use the normal of that plane and treat that as the right direction for your system.

 

So in other words it doesn't really matter where the profile is along a curve you just need to use the source plane it is sketched on to transform it to the XY plane and then back to the plane appropriate to the arbitrary point along the curve (since profile is consistent along swept path).

 

If you include a family file containing an example of the sweep you may get more help.

0 Likes
Message 6 of 6

islam.alqalyubi
Participant
Participant
Accepted solution

Thanks a lot, I found the source of the error. I was dealing with pathAttachmentParam as if it is the distance measured along the path curve from the curve start point up to the profile location divided by the total length of the curve so I was dealing with this parameter as if it is relative distance but I tried to use the absolute distance and it works.

islamalqalyubi_0-1701170645473.png