/// <summary> /// Calculate the signal attenuation between the /// given source and target points using ray tracing. /// Walls and distance through air cause losses. /// </summary> public double Attenuation(XYZ psource, XYZ ptarget) { #if DEBUG_GRAPHICAL Debug.Print(string.Format("{0} -> {1}", Util.PointString(psource), Util.PointString(ptarget))); if (null == _sketch || 0.0001 < _sketch.GetPlane().Origin.Z - psource.Z) { Plane plane = Plane.CreateByNormalAndOrigin( XYZ.BasisZ, psource); _sketch = SketchPlane.Create(_doc, plane); } Line line = Line.CreateBound(psource, ptarget); _sketch.Document.Create.NewModelCurve(line, _sketch); #endif // DEBUG_GRAPHICAL double d = ptarget.DistanceTo(psource); double a = Util.FootToMetre(d) * _settings.AttenuationAirPerMetreInDb; int wallCount = GetWallCount(psource, ptarget); a += wallCount * _settings.AttenuationWallInDb; return(a); }
RadialArray() { if (m_revitApp.ActiveUIDocument.Selection.GetElementIds().Count > 0) { Autodesk.Revit.DB.View view = m_revitApp.ActiveUIDocument.Document.ActiveView; XYZ axisDir = null; if (view is View3D) { SketchPlane sp = view.SketchPlane; if (sp == null) { return; } axisDir = sp.GetPlane().Normal; } else { axisDir = view.ViewDirection; } if (axisDir == null) { return; } Line axisLine = Line.CreateBound(XYZ.Zero, XYZ.Zero.Add(axisDir)); Autodesk.Revit.DB.RadialArray.Create( m_revitApp.ActiveUIDocument.Document, m_revitApp.ActiveUIDocument.Document.ActiveView, m_revitApp.ActiveUIDocument.Selection.GetElementIds(), 4, axisLine, 30.0, ArrayAnchorMember.Last); } }
/// <summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public Result Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, ElementSet elements) { try { m_application = commandData.Application; m_document = m_application.ActiveUIDocument; if (m_document.Document.IsFamilyDocument) { m_CreationBase = m_document.Document.FamilyCreate; } else { m_CreationBase = m_document.Document.Create; } //Pick a face from UI, create a new sketch plane via the face and set it to the current view. Reference faceRef = m_document.Selection.PickObject(ObjectType.Face, new PlanarFaceFilter(m_document.Document), "Please pick a planar face to set the work plane. ESC for cancel."); GeometryObject geoObject = m_document.Document.GetElement(faceRef).GetGeometryObjectFromReference(faceRef); PlanarFace planarFace = geoObject as PlanarFace; SketchPlane faceSketchPlane = CreateSketchPlane(planarFace.FaceNormal, planarFace.Origin); if (faceSketchPlane != null) { Transaction changeSketchPlane = new Transaction(m_document.Document, "Change Sketch Plane."); changeSketchPlane.Start(); m_document.Document.ActiveView.SketchPlane = faceSketchPlane; m_document.Document.ActiveView.ShowActiveWorkPlane(); changeSketchPlane.Commit(); } // Pick point from current work plane with snaps. ObjectSnapTypes snapType = ObjectSnapTypes.Centers | ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections | ObjectSnapTypes.Midpoints | ObjectSnapTypes.Nearest | ObjectSnapTypes.WorkPlaneGrid; XYZ point = m_document.Selection.PickPoint(snapType, "Please pick a point to place component."); // Create a model curve by a circle with picked point as center. Transaction createModelCurve = new Transaction(m_document.Document, "Create a circle."); createModelCurve.Start(); Curve circle = Arc.Create(point, 5, 0, Math.PI * 2, faceSketchPlane.GetPlane().XVec, faceSketchPlane.GetPlane().YVec); m_CreationBase.NewModelCurve(circle, faceSketchPlane); createModelCurve.Commit(); return(Result.Succeeded); } catch (Exceptions.OperationCanceledException) { // Selection Cancelled. For picking face and picking point. return(Result.Cancelled); } catch (System.Exception ex) { // If any error, give error information and return failed message = ex.Message; return(Result.Failed); } }
/// <summary> /// Return true if the sketch plane belongs to us /// and its origin and normal vector match the /// given targets. /// Nope, we are unable to set the sketch plane /// name. However, Revit throws an exception if /// we try to draw on the skatch plane named /// 'Level 1', so lets ensure we use '<not /// associated>'. /// </summary> static bool SketchPlaneMatches( SketchPlane sketchPlane, XYZ origin, XYZ normal) { //bool rc = sketchPlane.Name.StartsWith( // _sketch_plane_name_prefix ); bool rc = sketchPlane.Name.Equals( _sketch_plane_name_prefix2); if (rc) { Plane plane = sketchPlane.GetPlane(); rc = plane.Normal.IsAlmostEqualTo(normal) && IsAlmostZero(SignedDistanceTo( plane, origin)); } return(rc); }
internal static bool IsPlaneOrientationAcceptable(UIDocument uiDoc) { View v = uiDoc.ActiveGraphicalView; SketchPlane sp = uiDoc.ActiveGraphicalView.SketchPlane; Plane p = sp?.GetPlane(); if (p == null) { return(false); } double dp = Math.Abs(v.ViewDirection.DotProduct(p.Normal)); logMsgDbLn2("rotation acceptable?", dp.ToString()); if (dp < 0.05) { return(false); } return(true); }
/// <summary> /// Retrieve origin and direction of the left /// reference plane within the given family instance. /// </summary> static bool GetFamilyInstanceReferencePlaneLocation( FamilyInstance fi, out XYZ origin, out XYZ normal) { // by Fair59, in // https://forums.autodesk.com/t5/revit-api-forum/direction-of-reference-reference-plane-or-reference-line/m-p/7074163 bool found = false; origin = XYZ.Zero; normal = XYZ.Zero; Reference r = fi .GetReferences(FamilyInstanceReferenceType.Left) .FirstOrDefault(); if (null != r) { Document doc = fi.Document; using (Transaction t = new Transaction(doc)) { t.Start("Create Temporary Sketch Plane"); SketchPlane sk = SketchPlane.Create(doc, r); if (null != sk) { Plane pl = sk.GetPlane(); origin = pl.Origin; normal = pl.Normal; found = true; } t.RollBack(); } } return(found); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; double scale = 304.8; #region TEST ////cut line endpoints //XYZ v1 = new XYZ(0, 2000, 0)/scale; //XYZ v2 = new XYZ(6018, 2000, 0) / scale; ////rhino cut line endpoints // rg.Point3d rv0 = new rg.Point3d(0, 2000, 0); // rg.Point3d rv1 = new rg.Point3d(6018, 2000, 0); //rg.Point3d rv2 = new rg.Point3d(0, 2000, 1); ////rhino cut plane //rg.Plane cutPlane = new rg.Plane(rv0, rv1, rv2); ////wip points //rg.Point3d rv3 = new rg.Point3d(857, 203, 4597); //rg.Point3d rv4 = new rg.Point3d(857, 6221, 4597); //rg.Point3d rv5 = new rg.Point3d(9818, 6221, 4597); // //wip plane // rg.Plane rhinoPlane = new rg.Plane(rv3, rv4, rv5); // rg.Line intLine; // var result = rg.Intersect.Intersection.PlanePlane(cutPlane, rhinoPlane, out intLine); // using (Transaction t = new Transaction(doc, "Project Line")) // { // t.Start(); // SketchPlane sp = SketchPlane.Create(doc, RhinoToRevitPlane(cutPlane)); // doc.Create.NewModelCurve(RhinoToRevitLine(intLine), sp); // t.Commit(); // } // TaskDialog.Show("r", "Done"); #endregion #region Revit // SELECT THE LINE TO PROJECT AND CONSTRUCT THE PLANE TO INTERSECT THE MESH Reference lineToProject = uidoc.Selection.PickObject(ObjectType.Element, "Select cut Line"); Element lineElement = doc.GetElement(lineToProject); CurveElement curveLine = lineElement as CurveElement; LocationCurve lineLocation = lineElement.Location as LocationCurve; Line line = lineLocation.Curve as Line; rg.Line rhinoCutLine = new rg.Line(RevitToRhinoPoint(line.GetEndPoint(0)), RevitToRhinoPoint(line.GetEndPoint(1))); XYZ perpDir = line.Direction.CrossProduct(XYZ.BasisZ).Normalize(); Plane cutPlane = Plane.CreateByNormalAndOrigin(perpDir, line.GetEndPoint(0)); // GET THE MESH GEOMETRY Reference meshRef = uidoc.Selection.PickObject(ObjectType.Element, "Select Mesh"); Element e = doc.GetElement(meshRef); Options opt = new Options(); opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = false; opt.View = doc.ActiveView; GeometryElement geomElem = e.get_Geometry(opt); Mesh geomMesh = null; foreach (GeometryObject geomObj in geomElem) { GeometryInstance gi = geomObj as GeometryInstance; if (gi != null) { foreach (GeometryObject element in gi.GetInstanceGeometry()) { geomMesh = element as Mesh; } } else { geomMesh = geomObj as Mesh; } } int counter = 0; using (Transaction t = new Transaction(doc, "Project Line")) { t.Start(); SketchPlane sp = SketchPlane.Create(doc, cutPlane); XYZ spOrigin = sp.GetPlane().Origin; Debug.Write($"Sketch plane origin: {spOrigin}\n"); XYZ spNormal = sp.GetPlane().Normal; Debug.Write($"Sketch plane normal: {spNormal}\n"); Line spX = Line.CreateBound(spOrigin, spOrigin + XYZ.BasisZ * 100); Debug.Write($"line start: {spX.GetEndParameter(0)}\n"); Debug.Write($"line end: {spX.GetEndParameter(1)}\n"); ModelCurve mc = doc.Create.NewModelCurve(spX, sp); Debug.Write($"mc: {mc.Id}\n"); List <XYZ> intersectionPoints = new List <XYZ>(); for (int i = 0; i < geomMesh.NumTriangles; i++) { MeshTriangle triangle = geomMesh.get_Triangle(i); XYZ vertex1 = triangle.get_Vertex(0); XYZ vertex2 = triangle.get_Vertex(1); XYZ vertex3 = triangle.get_Vertex(2); rg.Point3d rhinoVertex1 = RevitToRhinoPoint(vertex1); rg.Point3d rhinoVertex2 = RevitToRhinoPoint(vertex2); rg.Point3d rhinoVertex3 = RevitToRhinoPoint(vertex3); List <rg.Line> rhinoEdges = new List <rg.Line> { new rg.Line(rhinoVertex1, rhinoVertex2), new rg.Line(rhinoVertex1, rhinoVertex2), new rg.Line(rhinoVertex1, rhinoVertex2) }; XYZ[] pts = new XYZ[2]; int ptscount = 0; foreach (rg.Line edge in rhinoEdges) { double a = 0; double b = 0; bool result = rg.Intersect.Intersection.LineLine(edge, rhinoCutLine, out a, out b); if (result) { intersectionPoints.Add(RhinoToRevitPoint(edge.PointAt(a))); pts[ptscount] = RhinoToRevitPoint(edge.PointAt(a)); ptscount = 1; counter++; } } if (pts[0] != null) { try { Line temp = Line.CreateBound(pts[0], pts[0] + XYZ.BasisZ * 100); //Line li = Line.CreateBound(pts[0], new XYZ(pts[0].X, pts[0].Y, pts[0].Z +100)); doc.Create.NewModelCurve(temp, sp); } catch { } } } t.Commit(); } TaskDialog.Show("Intersections found", counter.ToString()); #endregion return(Result.Succeeded); }
void commonInit(ExporterIFC exporterIFC, Element elem, Transform familyTrf, Transform orientationTrf, ElementId overrideLevelId) { m_ExporterIFC = exporterIFC; overrideLevelId = overrideLevelId != null ? overrideLevelId : ElementId.InvalidElementId; Document doc = elem.Document; Element hostElem = elem; ElementId elemId = elem.Id; ElementId newLevelId = overrideLevelId; bool useOverrideOrigin = false; XYZ overrideOrigin = XYZ.Zero; IDictionary <ElementId, IFCLevelInfo> levelInfos = exporterIFC.GetLevelInfos(); if (overrideLevelId == ElementId.InvalidElementId) { if (familyTrf == null) { // Override for CurveElems -- base level calculation on origin of sketch Plane. if (elem is CurveElement) { SketchPlane sketchPlane = (elem as CurveElement).SketchPlane; if (sketchPlane != null) { useOverrideOrigin = true; overrideOrigin = sketchPlane.GetPlane().Origin; } } else { ElementId hostElemId = ElementId.InvalidElementId; // a bit of a hack. If we have a railing, we want it to have the same level base as its host Stair (because of // the way the stairs place railings and stair flights together). if (elem is Railing) { hostElemId = (elem as Railing).HostId; } else if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Assemblies) { hostElemId = elem.AssemblyInstanceId; } if (hostElemId != ElementId.InvalidElementId) { hostElem = doc.GetElement(hostElemId); } newLevelId = hostElem != null ? hostElem.LevelId : ElementId.InvalidElementId; if (newLevelId == ElementId.InvalidElementId) { ExporterIFCUtils.GetLevelIdByHeight(exporterIFC, hostElem); } } } // todo: store. double bottomHeight = double.MaxValue; ElementId bottomLevelId = ElementId.InvalidElementId; if ((newLevelId == ElementId.InvalidElementId) || orientationTrf != null) { // if we have a trf, it might geometrically push the instance to a new level. Check that case. // actually, we should ALWAYS check the bbox vs the settings newLevelId = ElementId.InvalidElementId; XYZ originToUse = XYZ.Zero; bool originIsValid = useOverrideOrigin; if (useOverrideOrigin) { originToUse = overrideOrigin; } else { BoundingBoxXYZ bbox = elem.get_BoundingBox(null); if (bbox != null) { originToUse = bbox.Min; originIsValid = true; } else if (hostElem.Id != elemId) { bbox = hostElem.get_BoundingBox(null); if (bbox != null) { originToUse = bbox.Min; originIsValid = true; } } } // The original heuristic here was that the origin determined the level containment based on exact location: // if the Z of the origin was higher than the current level but lower than the next level, it was contained // on that level. // However, in some places (e.g. Germany), the containment is thought to start just below the level, because floors // are placed before the level, not above. So we have made a small modification so that anything within // 10cm of the 'next' level is on that level. double leveExtension = 10.0 / (12.0 * 2.54); foreach (KeyValuePair <ElementId, IFCLevelInfo> levelInfoPair in levelInfos) { // the cache contains levels from all the exported documents // if the export is performed for a linked document, filter the levels that are not from this document if (ExporterCacheManager.ExportOptionsCache.ExportingLink) { Element levelElem = doc.GetElement(levelInfoPair.Key); if (levelElem == null || !(levelElem is Level)) { continue; } } IFCLevelInfo levelInfo = levelInfoPair.Value; double startHeight = levelInfo.Elevation - leveExtension; double height = levelInfo.DistanceToNextLevel; bool useHeight = !MathUtil.IsAlmostZero(height); double endHeight = startHeight + height; if (originIsValid && ((originToUse[2] > (startHeight - MathUtil.Eps())) && (!useHeight || originToUse[2] < (endHeight - MathUtil.Eps())))) { newLevelId = levelInfoPair.Key; } if (startHeight < (bottomHeight + MathUtil.Eps())) { bottomLevelId = levelInfoPair.Key; bottomHeight = startHeight; } } } if (newLevelId == ElementId.InvalidElementId) { newLevelId = bottomLevelId; } } m_LevelInfo = exporterIFC.GetLevelInfo(newLevelId); if (m_LevelInfo == null) { foreach (KeyValuePair <ElementId, IFCLevelInfo> levelInfoPair in levelInfos) { // the cache contains levels from all the exported documents // if the export is performed for a linked document, filter the levels that are not from this document if (ExporterCacheManager.ExportOptionsCache.ExportingLink) { Element levelElem = doc.GetElement(levelInfoPair.Key); if (levelElem == null || !(levelElem is Level)) { continue; } } m_LevelInfo = levelInfoPair.Value; break; } //m_LevelInfo = levelInfos.Values.First<IFCLevelInfo>(); } double elevation = m_LevelInfo.Elevation; IFCAnyHandle levelPlacement = m_LevelInfo.GetLocalPlacement(); IFCFile file = exporterIFC.GetFile(); Transform trf = Transform.Identity; if (familyTrf != null) { XYZ origin, xDir, yDir, zDir; xDir = familyTrf.BasisX; yDir = familyTrf.BasisY; zDir = familyTrf.BasisZ; Transform origOffsetTrf = Transform.Identity; XYZ negLevelOrigin = new XYZ(0, 0, -elevation); origOffsetTrf.Origin = negLevelOrigin; Transform newTrf = origOffsetTrf * familyTrf; origin = newTrf.Origin; trf.BasisX = xDir; trf.BasisY = yDir; trf.BasisZ = zDir; trf = trf.Inverse; origin = UnitUtil.ScaleLength(origin); m_LocalPlacement = ExporterUtil.CreateLocalPlacement(file, levelPlacement, origin, zDir, xDir); } else if (orientationTrf != null) { XYZ origin, xDir, yDir, zDir; xDir = orientationTrf.BasisX; yDir = orientationTrf.BasisY; zDir = orientationTrf.BasisZ; origin = orientationTrf.Origin; XYZ levelOrigin = new XYZ(0, 0, elevation); origin = origin - levelOrigin; trf.BasisX = xDir; trf.BasisY = yDir; trf.BasisZ = zDir; trf.Origin = origin; trf = trf.Inverse; origin = UnitUtil.ScaleLength(origin); m_LocalPlacement = ExporterUtil.CreateLocalPlacement(file, levelPlacement, origin, zDir, xDir); } else { m_LocalPlacement = ExporterUtil.CreateLocalPlacement(file, levelPlacement, null, null, null); } Transform origOffsetTrf2 = Transform.Identity; XYZ negLevelOrigin2 = new XYZ(0, 0, -elevation); origOffsetTrf2.Origin = negLevelOrigin2; Transform newTrf2 = trf * origOffsetTrf2; m_ExporterIFC.PushTransform(newTrf2); m_Offset = elevation; m_LevelId = newLevelId; }
/// <summary> /// /// </summary> /// <param name="app"></param> /// <param name="sketchPlane"></param> /// <returns></returns> private static Revit.Element CloneElement(Autodesk.Revit.UI.UIApplication app, SketchPlane sketchPlane) { SketchPlane sketchPlaneClone = SketchPlane.Create(app.ActiveUIDocument.Document, sketchPlane.GetPlane()); Utils.ParamUtil.SetParameters(sketchPlaneClone.Parameters, sketchPlane.Parameters); return(sketchPlaneClone); }
private void Stream( ArrayList data, SketchPlane sketchPlane ) { data.Add( new Snoop.Data.ClassSeparator( typeof( SketchPlane ) ) ); data.Add( new Snoop.Data.Object( "Plane", sketchPlane.GetPlane() ) ); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { Application app = commandData.Application.Application; string filename = Path.Combine(_folder, _template); Document familyDoc = app.NewFamilyDocument(filename); Family family = familyDoc.OwnerFamily; Autodesk.Revit.Creation.FamilyItemFactory factory = familyDoc.FamilyCreate; Extrusion extrusion = null; using (Transaction trans = new Transaction( familyDoc)) { trans.Start("Create Extrusion"); XYZ arcCenter = new XYZ(0.0, 3.0, -2.0); // Get the "left" view View view = GetView(ViewType.Elevation, XYZ.BasisY.Negate(), XYZ.BasisZ, familyDoc); // 2D offsets from view 'left' XYZ xOffset = new XYZ(0.0, 10.0, 0.0); XYZ yOffset = new XYZ(0.0, 0.0, -10.0); //################## Reference planes ################################ // Origin's reference planes ReferencePlane referencePlaneOriginX = factory.NewReferencePlane(XYZ.BasisX, XYZ.Zero, XYZ.BasisY, view); referencePlaneOriginX.Name = "ReferencePlane_OriginX"; referencePlaneOriginX.Pinned = true; ReferencePlane referencePlaneOriginY = factory.NewReferencePlane(XYZ.BasisZ, XYZ.Zero, -XYZ.BasisX, view); referencePlaneOriginY.Name = "ReferencePlane_OriginY"; referencePlaneOriginY.Pinned = true; // Reference planes the extruded arc should stick to ReferencePlane referencePlaneX = factory.NewReferencePlane( XYZ.BasisX + yOffset, XYZ.Zero + yOffset, XYZ.BasisY, view); referencePlaneX.Name = "ReferencePlane_X"; ReferencePlane referencePlaneY = factory.NewReferencePlane( XYZ.BasisZ + xOffset, XYZ.Zero + xOffset, -XYZ.BasisX, view); referencePlaneY.Name = "ReferencePlane_Y"; familyDoc.Regenerate(); //################## Create dimensions ############################### // Dimension x ReferenceArray refArrayX = new ReferenceArray(); refArrayX.Append(referencePlaneX.GetReference()); refArrayX.Append(referencePlaneOriginX.GetReference()); Line lineX = Line.CreateUnbound(arcCenter, XYZ.BasisZ); Dimension dimensionX = factory.NewDimension( view, lineX, refArrayX); // Dimension y ReferenceArray refArrayY = new ReferenceArray(); refArrayY.Append(referencePlaneY.GetReference()); refArrayY.Append(referencePlaneOriginY.GetReference()); Line lineY = Line.CreateUnbound(arcCenter, XYZ.BasisY); Dimension dimensionY = factory.NewDimension( view, lineY, refArrayY); familyDoc.Regenerate(); //################## Create arc ###################################### double arcRadius = 1.0; Arc arc = Arc.Create( XYZ.Zero + xOffset + yOffset, arcRadius, 0.0, 2 * Math.PI, XYZ.BasisZ, XYZ.BasisY.Negate()); CurveArray curves = new CurveArray(); curves.Append(arc); CurveArrArray profile = new CurveArrArray(); profile.Append(curves); Plane plane = new Plane(XYZ.BasisX.Negate(), arcCenter); SketchPlane sketchPlane = SketchPlane.Create( familyDoc, plane); Debug.WriteLine("Origin: " + sketchPlane.GetPlane().Origin); Debug.WriteLine("Normal: " + sketchPlane.GetPlane().Normal); Debug.WriteLine("XVec: " + sketchPlane.GetPlane().XVec); Debug.WriteLine("YVec: " + sketchPlane.GetPlane().YVec); extrusion = factory.NewExtrusion(true, profile, sketchPlane, 10); familyDoc.Regenerate(); //################## Add family parameters ########################### FamilyManager fmgr = familyDoc.FamilyManager; FamilyParameter paramX = fmgr.AddParameter("X", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, true); dimensionX.FamilyLabel = paramX; FamilyParameter paramY = fmgr.AddParameter("Y", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, true); dimensionY.FamilyLabel = paramY; // Set their values FamilyType familyType = fmgr.NewType( "Standard"); fmgr.Set(paramX, 10); fmgr.Set(paramY, 10); trans.Commit(); } // Save it to inspect SaveAsOptions opt = new SaveAsOptions(); opt.OverwriteExistingFile = true; filename = Path.Combine(Path.GetTempPath(), "test.rfa"); familyDoc.SaveAs(filename, opt); return(Result.Succeeded); }
/// <summary> /// Exports a curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) { return; } SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == null) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcAnnotation; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.GetPlane(); XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else { useOffsetTrf = true; } Transform curveLCS = GeometryUtil.CreateTransformFromPlane(planeSK); curveLCS.Origin = origin; IList <IFCAnyHandle> curves = null; if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { Transform trf = null; if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; trf = Transform.CreateTranslation(offsetOrig); } curves = new List <IFCAnyHandle>(); //Curve curve = (geometryElement as GeometryObject) as Curve; List <Curve> curvesFromGeomElem = GeometryUtil.GetCurvesFromGeometryElement(geometryElement); foreach (Curve curve in curvesFromGeomElem) { IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve, trf); //IList<int> segmentIndex = null; //IList<IList<double>> pointList = GeometryUtil.PointListFromCurve(exporterIFC, curve, trf, null, out segmentIndex); //// For now because of no support in creating IfcLineIndex and IfcArcIndex yet, it is set to null ////IList<IList<int>> segmentIndexList = new List<IList<int>>(); ////segmentIndexList.Add(segmentIndex); //IList<IList<int>> segmentIndexList = null; //IFCAnyHandle pointListHnd = IFCInstanceExporter.CreateCartesianPointList3D(file, pointList); //IFCAnyHandle curveHnd = IFCInstanceExporter.CreateIndexedPolyCurve(file, pointListHnd, segmentIndexList, false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) { curves.Add(curveHnd); } } } else { IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, curveLCS, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.CreateTranslation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } curves = info.GetCurves(); } if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, curveLCS, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }
/// <summary> /// /// </summary> /// <param name="app"></param> /// <param name="sketchPlane"></param> /// <returns></returns> private static Revit.Element CloneElement( Autodesk.Revit.UI.UIApplication app, SketchPlane sketchPlane ) { SketchPlane sketchPlaneClone = SketchPlane.Create( app.ActiveUIDocument.Document, sketchPlane.GetPlane() ); Utils.ParamUtil.SetParameters( sketchPlaneClone.Parameters, sketchPlane.Parameters ); return sketchPlaneClone; }
/// <summary> /// Return true if the sketch plane belongs to us /// and its origin and normal vector match the /// given targets. /// Nope, we are unable to set the sketch plane /// name. However, Revit throws an exception if /// we try to draw on the skatch plane named /// 'Level 1', so lets ensure we use '<not /// associated>'. /// </summary> static bool SketchPlaneMatches( SketchPlane sketchPlane, XYZ origin, XYZ normal) { //bool rc = sketchPlane.Name.StartsWith( // _sketch_plane_name_prefix ); bool rc = sketchPlane.Name.Equals( _sketch_plane_name_prefix2 ); if( rc ) { Plane plane = sketchPlane.GetPlane(); rc = plane.Normal.IsAlmostEqualTo( normal ) && IsAlmostZero( SignedDistanceTo( plane, origin ) ); } return rc; }
private FamilyInstance LoadMassFamily(string fileName, Level level) { FamilyInstance familyInstance = null; using (Transaction trans = new Transaction(doc)) { trans.Start("Load Mass Family"); try { Family newFamily = null; bool loaded = doc.LoadFamily(fileName, new FamilyOption(), out newFamily); if (loaded) { #if RELEASE2013 || RELEASE2014 FamilySymbolSetIterator symbolIterator = newFamily.Symbols.ForwardIterator(); symbolIterator.MoveNext(); FamilySymbol symbol = symbolIterator.Current as FamilySymbol; #if RELEASE2013 FilteredElementCollector collector = new FilteredElementCollector(doc); SketchPlane skPlane = collector.OfClass(typeof(SketchPlane)).First <Element>(e => e.Name.Equals(level.Name)) as SketchPlane; familyInstance = doc.Create.NewFamilyInstance(new XYZ(0, 0, skPlane.Plane.Origin.Z), symbol, skPlane, StructuralType.NonStructural); #elif RELEASE2014 if (!symbol.IsActive) { symbol.Activate(); } SketchPlane skPlane = SketchPlane.Create(doc, level.Id); familyInstance = doc.Create.NewFamilyInstance(new XYZ(0, 0, skPlane.GetPlane().Origin.Z), symbol, skPlane, StructuralType.NonStructural); #endif #elif RELEASE2015 || RELEASE2016 List <ElementId> elementIds = newFamily.GetFamilySymbolIds().ToList(); if (elementIds.Count > 0) { ElementId symbolId = elementIds.First(); FamilySymbol fSymbol = doc.GetElement(symbolId) as FamilySymbol; if (null != fSymbol) { if (!fSymbol.IsActive) { fSymbol.Activate(); } SketchPlane skPlane = SketchPlane.Create(doc, level.Id); if (null != skPlane) { familyInstance = doc.Create.NewFamilyInstance(new XYZ(0, 0, skPlane.GetPlane().Origin.Z), fSymbol, skPlane, StructuralType.NonStructural); } } } #endif } trans.Commit(); } catch (Exception ex) { MessageBox.Show("Failed to load mass family.\n" + ex.Message, "MassCreator : Load Mass Family", MessageBoxButtons.OK, MessageBoxIcon.Warning); trans.RollBack(); } } return(familyInstance); }
/// <summary> /// Exports a curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) { return; } SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.GetPlane(); XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else { useOffsetTrf = true; } Plane plane = new Plane(planeSK.XVec, planeSK.YVec, origin); IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.CreateTranslation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } IList <IFCAnyHandle> curves = info.GetCurves(); if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, plane, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }
Result IExternalCommand.Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Autodesk.Revit.DB.Document revitDoc = commandData.Application.ActiveUIDocument.Document; //取得文档 Application revitApp = commandData.Application.Application; //取得应用程序 UIDocument uiDoc = commandData.Application.ActiveUIDocument; //取得当前活动文档 Selection sel = uiDoc.Selection; Reference ref1 = sel.PickObject(ObjectType.Element, "选择一个注释"); Element elem = revitDoc.GetElement(ref1); Dimension dimension = elem as Dimension; Curve curve = dimension.Curve; Line line = curve as Line; //XYZ SPoint = line.Origin; 这个注释的起点很神奇,不准而且还会变 XYZ CPoint = dimension.Origin; double LineLength = Convert.ToDouble(dimension.Value / 2); XYZ vec = line.Direction; //计算出最长的线的起始点,并创建线 XYZ EPoint = new XYZ(CPoint.X + LineLength * vec.X, CPoint.Y + LineLength * vec.Y, CPoint.Z + LineLength * vec.Z); XYZ SPoint = new XYZ(CPoint.X - LineLength * vec.X, CPoint.Y - LineLength * vec.Y, CPoint.Z - LineLength * vec.Z); Line line1 = Line.CreateBound(SPoint, EPoint); //XYZ temp = new XYZ(1, 1, 1); //XYZ normal = line.Direction.CrossProduct(temp); //应该去拿注释所在平面 SketchPlane sketchPlane = dimension.View.SketchPlane; XYZ normal = sketchPlane.GetPlane().Normal; //创建注释标 XYZ xYZ = normal.CrossProduct(line.Direction); double Dlength = 15; XYZ SPoint2 = new XYZ(SPoint.X + xYZ.X * LineLength / Dlength, SPoint.Y + xYZ.Y * LineLength / Dlength, SPoint.Z + xYZ.Z * LineLength / Dlength); XYZ SPoint3 = new XYZ(SPoint.X - xYZ.X * LineLength / Dlength, SPoint.Y - xYZ.Y * LineLength / Dlength, SPoint.Z - xYZ.Z * LineLength / Dlength); XYZ SPoint4 = new XYZ(EPoint.X + xYZ.X * LineLength / Dlength, EPoint.Y + xYZ.Y * LineLength / Dlength, EPoint.Z + xYZ.Z * LineLength / Dlength); XYZ SPoint5 = new XYZ(EPoint.X - xYZ.X * LineLength / Dlength, EPoint.Y - xYZ.Y * LineLength / Dlength, EPoint.Z - xYZ.Z * LineLength / Dlength); Line line2 = Line.CreateBound(SPoint2, SPoint3); Line line3 = Line.CreateBound(SPoint4, SPoint5); XYZ temp = new XYZ(1, 1, 1); XYZ normal2 = line2.Direction.CrossProduct(temp); XYZ normal3 = line3.Direction.CrossProduct(temp); //创建注释的起始终止线 using (Transaction tran = new Transaction(uiDoc.Document)) { tran.Start("测试"); uiDoc.Document.Create.NewModelCurve(line1, sketchPlane); Plane plane = Plane.CreateByNormalAndOrigin(normal2, SPoint); SketchPlane sketchPlane2 = SketchPlane.Create(uiDoc.Document, plane); uiDoc.Document.Create.NewModelCurve(line2, sketchPlane2); Plane plane1 = Plane.CreateByNormalAndOrigin(normal3, EPoint); SketchPlane sketchPlane3 = SketchPlane.Create(uiDoc.Document, plane1); uiDoc.Document.Create.NewModelCurve(line3, sketchPlane3); //放样成为一个体 //createExtrusionProfile(commandData, line1, 10); tran.Commit(); } return(Result.Succeeded); }