Message 1 of 1
Orientation Issue while creating new sweep geometry from Cable Tray information.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi all,
I’m trying to create a script that takes location, path and dimensions from existing Cable Tray and Cable Tray Fitting families and creates a new sweep rectangular geometry that starts on the bottom of the existing geometry, has same width but is 200mm higher, that will be a place holder for federated model.
I have two issues that I cannot solve: 1. New sweep is correctly created only on existing geometry that has X direction, all others are not correct, please see image below. 2. Exception error occurs, that I can’t find a solution to. If there is no solution, I’ll just skip this geometry and continue with the loop.
If anyone can help, I’ll be grateful.
Here is the code:
namespace TestFile
{
[Transaction(TransactionMode.Manual)]
public class TestClass : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//Get application and document objects
UIApplication uiapp = commandData.Application;
Document doc = uiapp.ActiveUIDocument.Document;
// Collect all Cable Tray elements in the document
FilteredElementCollector collectorTray = new FilteredElementCollector(doc);
ICollection<Element> cableTrays = collectorTray.OfCategory(BuiltInCategory.OST_CableTray).WhereElementIsNotElementType().ToElements();
// Collect all Cable tray fitting - Bend elements
FilteredElementCollector collectorFittings = new FilteredElementCollector(doc);
ICollection<Element> bendTtrays = collectorFittings.OfCategory(BuiltInCategory.OST_CableTrayFitting).WhereElementIsNotElementType().ToElements();
// Collect all Generic Cable tray place holder previously created
FilteredElementCollector genericCollector = new FilteredElementCollector(doc);
IEnumerable<Element> existingPlaceHolder = genericCollector.OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsNotElementType().ToElements();
existingPlaceHolder.Where(e => e.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).AsValueString().Equals("Tray Place holder"));
List<Element> existingPlaceHolderList = new List<Element>();
existingPlaceHolderList.AddRange(existingPlaceHolder);
//List of all Cable trays
List<ICollection<Element>> allTrays = new List<ICollection<Element>> { cableTrays };
allTrays.Add(bendTtrays);
List<Element> elementTrays = new List<Element>();
foreach (ICollection<Element> collector in allTrays)
{
foreach (Element elementTray in collector)
{
elementTrays.Add(elementTray);
}
}
Transaction trans = new Transaction(doc);
// Define the color and transparency
Color color = new Color(255, 0, 0); // Red color
int transparency = 50; // 50% transparency
// Create OverrideGraphicSettings
OverrideGraphicSettings overrideSettings = new OverrideGraphicSettings();
overrideSettings.SetProjectionLineColor(color);
overrideSettings.SetSurfaceForegroundPatternColor(color);
overrideSettings.SetSurfaceTransparency(transparency);
try
{
// Delete previously created sweep geometry
if (existingPlaceHolderList.Count > 0)
{
trans.Start("Delete old generic cable tray models");
foreach (Element element in existingPlaceHolderList)
{
doc.Delete(element.Id);
}
trans.Commit();
}
if (elementTrays.Count > 0)
{
foreach (Element cableTray in elementTrays)
{
Category category = cableTray.Category;
if (category.Id.IntegerValue != (int)BuiltInCategory.OST_CableTray) // takes in Cable Tray Fitting
{
trans.Start("test");
LocationPoint locationPoint = cableTray.Location as LocationPoint;
XYZ point = locationPoint.Point; // has same value as origin
double rotation = locationPoint.Rotation;
Options options = new Options();
options.ComputeReferences = true;
options.DetailLevel = ViewDetailLevel.Coarse; //Needs to be Coarse to work with ARC, other detail lvl do NOT work
GeometryElement geometryElement = cableTray.get_Geometry(options);
foreach (GeometryInstance geoInst in geometryElement)
{
if (geoInst != null)
{
foreach (GeometryObject obj in geoInst.GetInstanceGeometry())
{
if (obj is Arc)
{
Arc arc = (Arc)obj;
Curve objCurve = (Curve)obj;
CurveLoop pathLoop = new CurveLoop();
pathLoop.Append(objCurve);
Curve firstCurve = pathLoop.ElementAt(0);
// Get height and width from cable tray
double trayHeight = cableTray.LookupParameter("Tray Height").AsDouble();
double trayWidth = cableTray.LookupParameter("Tray Width").AsDouble();
//get the point to create a plane for the profile.
XYZ xyzFirstpoint = firstCurve.GetEndPoint(0);
// Create Plane
Transform transform = firstCurve.ComputeDerivatives(0, true);
XYZ xyzDirection = transform.BasisX;
Plane profilePlane = Plane.CreateByNormalAndOrigin(xyzDirection.Normalize(), transform.Origin);
double dblHeight = trayHeight + 0.65616797900262469; // increase height by 200mm
double dblWidth = trayWidth;
List<CurveLoop> newloops = new List<CurveLoop> { sweepProfileLoop(dblHeight, dblWidth, profilePlane) };
Solid solid = GeometryCreationUtilities.CreateSweptGeometry(pathLoop, 0, objCurve.GetEndParameter(0), newloops);
DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.SetShape(new List<GeometryObject>() { solid });
doc.ActiveView.SetElementOverrides(ds.Id, overrideSettings);
}
}
}
}
trans.Commit();
}
else
{
trans.Start("test");
LocationCurve location = cableTray.Location as LocationCurve;
Curve curve = location.Curve;
Line line = curve as Line;
XYZ direction = line.Direction;
XYZ origin = line.Origin;
double length = cableTray.LookupParameter("Length").AsDouble();
CurveLoop pathLoop = new CurveLoop();
pathLoop.Append(curve);
Curve firstCurve = pathLoop.ElementAt(0);
// Get height and width from cable tray
double trayHeight = cableTray.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).AsDouble();
double trayWidth = cableTray.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).AsDouble();
//get the point to create a plane for the profile.
XYZ xyzFirstpoint = firstCurve.GetEndPoint(0);
// Create Plane
Transform transform = firstCurve.ComputeDerivatives(0, true);
XYZ xyzDirection = transform.BasisX;
Plane profilePlane = Plane.CreateByNormalAndOrigin(xyzDirection.Normalize(), transform.Origin);
//Create a profile which is a rectangle with height and width of the cable tray
List<CurveLoop> newloops = new List<CurveLoop> { sweepProfileLoop(trayHeight, trayWidth, profilePlane) };
Solid solid = GeometryCreationUtilities.CreateSweptGeometry(pathLoop, 0, curve.GetEndParameter(0), newloops);
DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
ds.SetShape(new List<GeometryObject>() { solid });
doc.ActiveView.SetElementOverrides(ds.Id, overrideSettings);
trans.Commit();
}
}
}
}
catch (Exception ex)
{
TaskDialog.Show("Exception error", ex.Message);
trans.RollBack();
return Result.Failed;
}
return Result.Succeeded;
}
//Create a profile which is a rectangle with height and width of the cable tray
private CurveLoop sweepProfileLoop(double height, double width, Plane plane)
{
double dblHeight = height + 0.65616797900262469; // increase height by 200mm
double dblWidth = width;
UV uvPt0 = new UV(0, -height/2) - new UV(dblWidth / 2, 0);
UV uvPt1 = uvPt0 + new UV(dblWidth, 0);
UV uvPt2 = uvPt1 + new UV(0, dblHeight);
UV uvPt3 = uvPt2 - new UV(dblWidth, 0);
XYZ xVec = plane.XVec;
XYZ yVec = plane.YVec;
XYZ xyzPt0 = plane.Origin + plane.XVec.Multiply(uvPt0.U) + plane.YVec.Multiply(uvPt0.V);
XYZ xyzPt1 = plane.Origin + plane.XVec.Multiply(uvPt1.U) + plane.YVec.Multiply(uvPt1.V);
XYZ xyzPt2 = plane.Origin + plane.XVec.Multiply(uvPt2.U) + plane.YVec.Multiply(uvPt2.V);
XYZ xyzPt3 = plane.Origin + plane.XVec.Multiply(uvPt3.U) + plane.YVec.Multiply(uvPt3.V);
Line l1 = Line.CreateBound(xyzPt0, xyzPt1);
Line l2 = Line.CreateBound(xyzPt1, xyzPt2);
Line l3 = Line.CreateBound(xyzPt2, xyzPt3);
Line l4 = Line.CreateBound(xyzPt3, xyzPt0);
CurveLoop loop = new CurveLoop();
loop.Append(l1);
loop.Append(l2);
loop.Append(l3);
loop.Append(l4);
return loop;
}
}
}