Sweep Profile Offset Alignment with Sweep Path in Family Document.

Sweep Profile Offset Alignment with Sweep Path in Family Document.

philbugmen
Contributor Contributor
789 Views
4 Replies
Message 1 of 5

Sweep Profile Offset Alignment with Sweep Path in Family Document.

philbugmen
Contributor
Contributor

I have made much progress in Getting the Sweep Profile to align. Though I think that I am having to input much effort in terms of creating workaround methods to realign something that has already been built as a model-in-place sweep within a project document. Here are the steps I am going through, simply.

1. Get a Sweep from a Project Document

2. Iterate through the pathSketch.Profile and build a curve array...

foreach (CurveArray curveArray in sweep.PathSketch.Profile)
{
foreach (Curve curve in curveArray)
{
if (pathStart == null)
{
pathStart = curve.GetEndPoint(0);
firstPathCurve = curve;
}
pathSketch.Append(curve);
}
}

3. Create a profile CurveArrArray offset from the centre of the first segments sweep path, if i do not do this step the sweep wont form correctly....

private static CurveArrArray CreateCoplanarProfile(CurveArrArray sweepProfile, XYZ direction, double length)
{
CurveArrArray coplanarProfiles = new CurveArrArray();

foreach (CurveArray curveArray in sweepProfile)
{
CurveArray offsetCurveArray = new CurveArray();

foreach (Curve curve in curveArray)
{
XYZ startPoint = curve.GetEndPoint(0);
XYZ endPoint = curve.GetEndPoint(1);
XYZ offsetVector = direction * length * 0.5;

XYZ offsetStartPoint = startPoint + offsetVector;
XYZ offsetEndPoint = endPoint + offsetVector;

Line offsetLine = Line.CreateBound(offsetStartPoint, offsetEndPoint);

offsetCurveArray.Append(offsetLine);
}

// Add the offset curve array to the coplanar profile.
coplanarProfiles.Append(offsetCurveArray);
}

return coplanarProfiles;
}

 

4. Using the new Profile CurveArrArray that is at the start of the first segment, I rotate the profile into the XY Plane...

private static CurveArrArray CreateTransformedProfile(Document doc, CurveArrArray curveArrArrayProfile, XYZ normalPath, XYZ originPath)
{
using (Transaction t = new Transaction(doc, "Create Transformed Profile"))
{
t.Start();

Transform transform = ConvertXYZProfileToXYProfile(normalPath, originPath);

CurveArrArray transformedProfile = new CurveArrArray();

foreach (CurveArray curveArray in curveArrArrayProfile)
{
CurveArray transformedCurveArray = new CurveArray();
foreach (Curve curve in curveArray)
{
transformedCurveArray.Append(curve.CreateTransformed(transform));
}
transformedProfile.Append(transformedCurveArray);
}

t.Commit();

return transformedProfile;
}
}

private static Transform ConvertXYZProfileToXYProfile(XYZ normal, XYZ origin)
{
double angle1 = XYZ.BasisZ.AngleTo(normal);
XYZ axis1 = normal.CrossProduct(XYZ.BasisZ);
Transform transform1 = Transform.CreateRotationAtPoint(axis1, angle1, origin);

double angle2 = normal.AngleTo(XYZ.BasisY);
double angleOffset = IsOppositeDirection(normal, angle2);
XYZ axis2 = normal;
Transform transform2 = Transform.CreateRotationAtPoint(axis2, angle2 + angleOffset, origin);
Transform transform = transform1.Multiply(transform2);

return transform;
}

 

5. Rotate the CurveArrArray Profile so that it is correctly oriented. The curveArrArray profile rotation requires an offset to get the rotation angle correct depending on the original rotation of the sweep path? in plan according to my testing I had to rotate many times and create this method to force the rotation of the sweep profile in the family to be correct. 

 

private static double IsOppositeDirection(XYZ normal, double angle2)
{
XYZ cross = normal.CrossProduct(XYZ.BasisY);

if (cross.Z > 0)
{
TaskDialog.Show("direction", "The angle is to the right of the Y axis");
return Math.PI;
}
else if (cross.Z < -0.001)
{
TaskDialog.Show("direction", (180 / Math.PI * angle2).ToString() + "The angle is to the left of the Y axis");
return Math.Abs(angle2 - Math.PI / 2) < 0.001 ? 0 :
(angle2 < (Math.PI / 2) - 0.001) ? -(Math.PI * 1.5) :
(angle2 > (Math.PI / 2) + 0.001) ? (Math.PI * 1.5) :
0;
}
else
{
TaskDialog.Show("direction", "The angle is either zero or 180 degrees");
return Math.PI;
}
}

 

6. I might be near to the end now, or maybe I am just going to find one more hurdle? 

However if in the project document i offset the sweep from the 0,0,0 point there is one more erroneous offset of the profile orientation away from the sweep Path to solve. You can see in fig 1, the middle line is the sweep path and the bottom image fig2, the offset of the profile ion the family, where the sweep path behaves and does not move. this erroneous offset occurs in all directions when the path is moved away from the 0,0,0, except if the sweep is moved upwards on the y-plane.

 

fig1.

SweepOffsetProject.PNG

 

fig2.

SweepOffsetFamilyExtra.PNG 

My Question is is all this extra code necessary  or am I missing the correct method to rotate the Sweep Profile into the XY plane of a family document? If you know a better method or if i am missing something please direct me to the post or even just let me know as I would really like a simpler more reliable method.

0 Likes
Accepted solutions (2)
790 Views
4 Replies
Replies (4)
Message 2 of 5

FAIR59
Advisor
Advisor

From my limited ( and simple ) test, you have all the information available in the profilesketch. I verified that the origin of the (sketch) plane lies on a curve off the sweep-path; the resulting profile is located where I expected it to be and all Z-values were zero.

		private CurveArrArray GetXYProfile(Sketch profilesketch)
		{
			SketchPlane sPlane = profilesketch.SketchPlane;
			Plane plane = sPlane.GetPlane();
			
			Transform trans = Transform.Identity;
			trans.Origin = plane.Origin;
			trans.BasisX = plane.XVec;
			trans.BasisY = plane.YVec;
			trans.BasisZ = plane.Normal;
			Transform toXYPlane = trans.Inverse;
			
			CurveArrArray coplanarXYProfiles = new CurveArrArray();
			foreach (CurveArray curveArray in profilesketch.Profile)
			{
				CurveArray offsetCurveArray = new CurveArray();
				foreach (Curve curve in curveArray)
				{
					Curve newcrv = curve.CreateTransformed(toXYPlane);
					offsetCurveArray.Append(newcrv);
				}
				coplanarXYProfiles.Append(offsetCurveArray);
			}
			return  coplanarXYProfiles;
		}

 then in the Family create a Sweep using a constructed SweepProfile from the above result

			Document doc;
			Sketch profilesketch = sweep.ProfileSketch;
			CurveArrArray XY_profileLoop = GetXYProfile(profilesketch);
			SweepProfile profile = 	doc.Application.Create.NewCurveLoopsProfile(XY_profileLoop);
			doc.FamilyCreate.NewSweep(true, _path, _path_sketchplane, profile, 0, ProfilePlaneLocation.MidPoint);

 

Message 3 of 5

philbugmen
Contributor
Contributor
Accepted solution

Fair,

I tested a few orientations of the sweep path, offsets from level and multiple path segments all worked as expected, thank you.

Further I am not familiar with transform identities and the transform inverse. If you have time could you pls explain how it works?

 

0 Likes
Message 4 of 5

RPTHOMAS108
Mentor
Mentor
Accepted solution

Identity transform in effect represents no transformation so is not the important aspect. Changing the basis and the origin of the transform represents a new position and orientation within the model and the inverse is the opposite of that.

 

In above example the new sweep profile needs to be defined on the XY plane so translation is required from current model profile position to XY plane based on the model directions of the sweep profile plane (XVec, YVec, Normal). The inverse is therefore translating the sweep profile plane system to the XY plane.

Message 5 of 5

philbugmen
Contributor
Contributor

thanx rpthomas

0 Likes