Stream(ArrayList data, RebarConstraint rbc) { data.Add(new Snoop.Data.ClassSeparator(typeof(RebarConstraint))); data.Add(new Snoop.Data.Bool("IsValid", rbc.IsValid())); if (!rbc.IsValid()) { return; } data.Add(new Snoop.Data.String("ConstraintType", rbc.GetConstraintType().ToString())); data.Add(new Snoop.Data.Object("TargetElement", rbc.GetTargetElement())); RebarConstraintType type = rbc.GetConstraintType(); if (type == RebarConstraintType.FixedDistanceToHostFace) { data.Add(new Snoop.Data.Double("Distance to Target Host Face", rbc.GetDistanceToTargetHostFace())); } if (type != RebarConstraintType.ToOtherRebar) { data.Add(new Snoop.Data.String("Target Host Face Type", rbc.GetRebarConstraintTargetHostFaceType().ToString())); data.Add(new Snoop.Data.Object("Target Host Face Reference", rbc.GetTargetHostFaceReference())); } if (type == RebarConstraintType.ToOtherRebar) { data.Add(new Snoop.Data.String("Rebar Constraint Type", rbc.GetTargetRebarConstraintType().ToString())); if (rbc.GetTargetRebarConstraintType() == TargetRebarConstraintType.BarBend) { data.Add(new Snoop.Data.Int("Target RebarBendNumber", rbc.GetTargetRebarBendNumber())); } } }
CollectEvent(object sender, CollectorEventArgs e) { // cast the sender object to the SnoopCollector we are expecting Collector snoopCollector = sender as Collector; if (snoopCollector == null) { Debug.Assert(false); // why did someone else send us the message? return; } // see if it is a type we are responsible for Color color = e.ObjToSnoop as Color; if (color != null) { Stream(snoopCollector.Data(), color); return; } LayoutRule layoutRule = e.ObjToSnoop as LayoutRule; if (layoutRule != null) { Stream(snoopCollector.Data(), layoutRule); return; } FormatOptions formatOptions = e.ObjToSnoop as FormatOptions; if (formatOptions != null) { Stream(snoopCollector.Data(), formatOptions); return; } CurtainGrid curtainGrid = e.ObjToSnoop as CurtainGrid; if (curtainGrid != null) { Stream(snoopCollector.Data(), curtainGrid); return; } CurtainCell curtainCell = e.ObjToSnoop as CurtainCell; if (curtainCell != null) { Stream(snoopCollector.Data(), curtainCell); return; } RebarHostData rebarHostData = e.ObjToSnoop as RebarHostData; if (rebarHostData != null) { Stream(snoopCollector.Data(), rebarHostData); return; } Leader leader = e.ObjToSnoop as Leader; if (leader != null) { Stream(snoopCollector.Data(), leader); return; } AreaVolumeSettings areaSettings = e.ObjToSnoop as AreaVolumeSettings; if (areaSettings != null) { Stream(snoopCollector.Data(), areaSettings); return; } ViewSheetSetting viewSheetSetting = e.ObjToSnoop as ViewSheetSetting; if (viewSheetSetting != null) { Stream(snoopCollector.Data(), viewSheetSetting); return; } Autodesk.Revit.UI.Events.DialogBoxData dlgBoxData = e.ObjToSnoop as Autodesk.Revit.UI.Events.DialogBoxData; if (dlgBoxData != null) { Stream(snoopCollector.Data(), dlgBoxData); return; } Construction construct = e.ObjToSnoop as Construction; if (construct != null) { Stream(snoopCollector.Data(), construct); return; } FamilyElementVisibility famElemVisib = e.ObjToSnoop as FamilyElementVisibility; if (famElemVisib != null) { Stream(snoopCollector.Data(), famElemVisib); return; } FamilyManager famManager = e.ObjToSnoop as FamilyManager; if (famManager != null) { Stream(snoopCollector.Data(), famManager); return; } FamilyParameter famParam = e.ObjToSnoop as FamilyParameter; if (famParam != null) { Stream(snoopCollector.Data(), famParam); return; } FamilyType famType = e.ObjToSnoop as FamilyType; if (famType != null) { Stream(snoopCollector.Data(), famType); return; } MEPSpaceConstruction mepSpaceConstuct = e.ObjToSnoop as MEPSpaceConstruction; if (mepSpaceConstuct != null) { Stream(snoopCollector.Data(), mepSpaceConstuct); return; } BuildingSiteExportOptions bldSiteExpOptions = e.ObjToSnoop as BuildingSiteExportOptions; if (bldSiteExpOptions != null) { Stream(snoopCollector.Data(), bldSiteExpOptions); return; } DGNExportOptions dgnExpOptions = e.ObjToSnoop as DGNExportOptions; if (dgnExpOptions != null) { Stream(snoopCollector.Data(), dgnExpOptions); return; } DWFExportOptions dwfExpOptions = e.ObjToSnoop as DWFExportOptions; if (dwfExpOptions != null) { Stream(snoopCollector.Data(), dwfExpOptions); return; } DWGExportOptions dwgExpOptions = e.ObjToSnoop as DWGExportOptions; if (dwgExpOptions != null) { Stream(snoopCollector.Data(), dwgExpOptions); return; } DWGImportOptions dwgImpOptions = e.ObjToSnoop as DWGImportOptions; if (dwgImpOptions != null) { Stream(snoopCollector.Data(), dwgImpOptions); return; } FBXExportOptions fbxExpOptions = e.ObjToSnoop as FBXExportOptions; if (fbxExpOptions != null) { Stream(snoopCollector.Data(), fbxExpOptions); return; } TrussMemberInfo trussInfo = e.ObjToSnoop as TrussMemberInfo; if (trussInfo != null) { Stream(snoopCollector.Data(), trussInfo); return; } VertexIndexPair vertIndPair = e.ObjToSnoop as VertexIndexPair; if (vertIndPair != null) { Stream(snoopCollector.Data(), vertIndPair); return; } PointElementReference ptElemRef = e.ObjToSnoop as PointElementReference; if (ptElemRef != null) { Stream(snoopCollector.Data(), ptElemRef); return; } Autodesk.Revit.DB.Architecture.BoundarySegment boundSeg = e.ObjToSnoop as Autodesk.Revit.DB.Architecture.BoundarySegment; if (boundSeg != null) { Stream(snoopCollector.Data(), boundSeg); return; } PointLocationOnCurve ptLocOnCurve = e.ObjToSnoop as PointLocationOnCurve; if (ptLocOnCurve != null) { Stream(snoopCollector.Data(), ptLocOnCurve); return; } Entity entity = e.ObjToSnoop as Entity; if (entity != null) { Stream(snoopCollector.Data(), entity); return; } Field field = e.ObjToSnoop as Field; if (field != null) { Stream(snoopCollector.Data(), field); return; } ExtensibleStorageField storeagefield = e.ObjToSnoop as ExtensibleStorageField; if (storeagefield != null) { Stream(snoopCollector.Data(), storeagefield); return; } IList <Autodesk.Revit.DB.BoundarySegment> boundSegs = e.ObjToSnoop as IList <Autodesk.Revit.DB.BoundarySegment>; if (boundSegs != null) { Stream(snoopCollector.Data(), boundSegs); return; } if (e.ObjToSnoop is KeyValuePair <String, String> ) { KeyValuePair <String, String> stringspair = (KeyValuePair <String, String>)e.ObjToSnoop; Stream(snoopCollector.Data(), stringspair); return; } Schema schema = e.ObjToSnoop as Schema; if (schema != null) { Stream(snoopCollector.Data(), schema); return; } ElementId elemId = e.ObjToSnoop as ElementId; if (elemId != null) { Stream(snoopCollector.Data(), elemId); return; } PlanViewRange plvr = e.ObjToSnoop as PlanViewRange; if (plvr != null) { Stream(snoopCollector.Data(), plvr); return; } //TF RebarConstraintsManager rbcm = e.ObjToSnoop as RebarConstraintsManager; if (rbcm != null) { Stream(snoopCollector.Data(), rbcm); return; } RebarConstrainedHandle rbch = e.ObjToSnoop as RebarConstrainedHandle; if (rbch != null) { Stream(snoopCollector.Data(), rbch); return; } RebarConstraint rbc = e.ObjToSnoop as RebarConstraint; if (rbc != null) { Stream(snoopCollector.Data(), rbc); return; } //TFEND if (Utils.IsSupportedType(e.ObjToSnoop) && e.ObjToSnoop != null) { Utils.StreamWithReflection(snoopCollector.Data(), e.ObjToSnoop.GetType(), e.ObjToSnoop); } }
Stream(ArrayList data, RebarConstraint rbc) { data.Add(new Snoop.Data.ClassSeparator(typeof(RebarConstraint))); data.Add(new Snoop.Data.Bool("IsValid", rbc.IsValid())); data.Add(new Snoop.Data.String("ConstraintType", rbc.GetConstraintType().ToString())); if (rbc.GetConstraintType() == RebarConstraintType.FixedDistanceToHostFace) { data.Add(new Snoop.Data.Double("Distance to Target Host Face", rbc.GetDistanceToTargetHostFace())); } if (rbc.GetConstraintType() != RebarConstraintType.ToOtherRebar) { data.Add(new Snoop.Data.String("Target Host Face Type", rbc.GetRebarConstraintTargetHostFaceType().ToString())); } if (rbc.GetConstraintType() == RebarConstraintType.ToOtherRebar) { data.Add(new Snoop.Data.String("Rebar Constraint Type", rbc.GetTargetRebarConstraintType().ToString())); if (rbc.GetTargetRebarConstraintType() == TargetRebarConstraintType.BarBend) { data.Add(new Snoop.Data.Int("Target RebarBendNumber", rbc.GetTargetRebarBendNumber())); } } }
/// <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 virtual Result Execute(ExternalCommandData commandData , ref string message, ElementSet elements) { try { Document doc = commandData.Application.ActiveUIDocument.Document; if (doc == null) { return(Result.Failed); } //Fetch a RebarBarType element to be used in Rebar creation. FilteredElementCollector fec = new FilteredElementCollector(doc).OfClass(typeof(RebarBarType)); if (fec.GetElementCount() <= 0) { return(Result.Failed); } RebarBarType barType = fec.FirstElement() as RebarBarType; Rebar rebar = null; CurveElement curveElem = null; using (Transaction tran = new Transaction(doc, "Create Rebar")) { Element host = null; Selection sel = commandData.Application.ActiveUIDocument.Selection; try { //Select structural Host. Reference hostRef = sel.PickObject(ObjectType.Element, "Select Host"); host = doc.GetElement(hostRef.ElementId); if (host == null) { return(Result.Failed); } } catch (Exception e) { message = e.Message; return(Result.Failed); } try { //Select curve element Reference lineRef = sel.PickObject(ObjectType.Element, "Select Model curve"); curveElem = doc.GetElement(lineRef.ElementId) as CurveElement; } catch (Exception) { curveElem = null; } tran.Start(); // Create Rebar Free Form by specifying the GUID defining the custom external server. // The Rebar element returned needs to receive constraints, so that regeneration can // call the custom geometry calculations and create the bars rebar = Rebar.CreateFreeForm(doc, RebarUpdateServer.SampleGuid, barType, host); // Get all bar handles to set constraints to them, so that the bar can generate its geometry RebarConstraintsManager rManager = rebar.GetRebarConstraintsManager(); IList <RebarConstrainedHandle> handles = rManager.GetAllHandles(); // if bar has no handles then the server can't generate rebar geometry if (handles.Count <= 0) { tran.RollBack(); return(Result.Failed); } // iterate through the rebar handles and prompt for face selection for each of them, to get user input foreach (RebarConstrainedHandle handle in handles) { if (handle.GetHandleType() == RebarHandleType.StartOfBar || handle.GetHandleType() == RebarHandleType.EndOfBar) { continue;// Start handle and end handle will receive constraints from the custom external server execution } try { Reference reference = sel.PickObject(ObjectType.Face, "Select face for " + handle.GetHandleName()); if (reference == null) { continue; } // create constraint using the picked faces and set it to the associated handle List <Reference> refs = new List <Reference>(); refs.Add(reference); RebarConstraint constraint = RebarConstraint.Create(handle, refs, true, 0.0); rManager.SetPreferredConstraintForHandle(handle, constraint); } catch (Exception e) { message = e.Message; tran.RollBack(); return(Result.Cancelled); } } try { //here we add a value to the shared parameter and add it to the regeneration dependencies Parameter newSharedParam = rebar.LookupParameter(AddSharedParams.m_paramName); Parameter newSharedParam2 = rebar.LookupParameter(AddSharedParams.m_CurveIdName); if (newSharedParam != null && newSharedParam2 != null) { newSharedParam.Set(0); newSharedParam2.Set(curveElem == null ? -1 : curveElem.Id.IntegerValue); RebarFreeFormAccessor accesRebar = rebar.GetFreeFormAccessor(); accesRebar.AddUpdatingSharedParameter(newSharedParam.Id); accesRebar.AddUpdatingSharedParameter(newSharedParam2.Id); } else { // The AddSharedParams command should be executed to create and bind these parameters to rebar. } } catch (Exception ex) { message = ex.Message; tran.RollBack(); return(Result.Cancelled); } tran.Commit(); return(Result.Succeeded); } } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }
/// <summary> /// function used to extract offset value from constraint /// </summary> /// <param name="updateData"> data used to pass or get information regarding constraints cover</param> /// <param name="constraint">constraint from which we extract the offset information</param> /// <param name="targetIdx">index of target in constraint</param> /// <param name="offset"> output value </param> /// <returns></returns> public static bool getOffsetFromConstraintAtTarget(RebarUpdateCurvesData updateData, RebarConstraint constraint, int targetIdx, out double offset) { offset = 0.0; if (updateData == null || constraint == null) { return(false); } double barDiam = updateData.GetBarModelDiameter(); var rebarStyle = updateData.GetRebarStyle(); var attachment = updateData.GetAttachmentType(); bool bIsInside = rebarStyle == RebarStyle.Standard || (rebarStyle != RebarStyle.Standard && attachment == StirrupTieAttachmentType.InteriorFace); if (constraint.IsToCover()) { if (targetIdx < 0 || targetIdx >= constraint.NumberOfTargets) { return(false); // incorrect index } RebarCoverType coverType = constraint.GetTargetCoverType(targetIdx); double coverDist = (coverType == null) ? 0.0 : coverType.CoverDistance; double diameterOffset = (barDiam / 2); if (bIsInside) { diameterOffset *= -1; } offset = constraint.GetDistanceToTargetCover() - coverDist + diameterOffset; return(true); } offset = constraint.GetDistanceToTargetHostFace(); return(true); }
/// <summary> /// Function used to adjust the computed geometry information of the rebar element and has two logical parts: /// - Selection of structural faces for creation of Start of Bar and End of Bar Constraints when needed /// (Constraints created here are visible and modifiable in the Graphical Constraints Manager in native Revit) /// The constraint search is done by listing all the faces from the structural pointed to by the FirstHandle constraint /// and then picking the face that has the closest intersection point with either the curves in the rebar, or their extensions /// - Adjustments are done to the start/end of the bars according to the corresponding constraints /// Each bar will be lengthened to the intersection point of the tangent in the curve's specified end with the corresponding constraint face, /// or it will be shortened to the intersection point of the curve itself with the corresponding constraint face. /// - Hook normals for each bar are calculated for the newly modified curves. /// This function is called after the successful execution of GenerateCurves /// </summary> /// <param name="data">Class used to pass information from the external application to the internal Rebar Element. /// Interfaces with the Rebar Element and exposes information needed for Constraint creation, face searching, and /// receives the result of the Start/End constraint calculation. /// updates are done on the element after the entire function finished successfully. /// </param> /// <returns> true if execution was completed successfully, false otherwise</returns> public bool TrimExtendCurves(RebarTrimExtendData data) { if (getSelectedCurveElement(getCurrentRebar(data.GetRebarUpdateCurvesData()), data.GetRebarUpdateCurvesData()) != null) { return(true); } // extract the curves from the element. IList <Curve> allbars = new List <Curve>(); for (int ii = 0; ii < data.GetRebarUpdateCurvesData().GetBarsNumber(); ii++) { allbars.Add(data.GetRebarUpdateCurvesData().GetBarGeometry(ii)[0]); } // Place for caching the faces of the host used in constraint search. List <TargetFace> hostFaces = new List <TargetFace>(); // repeat process for each end of the Rebar. for (int iBarEnd = 0; iBarEnd < 2; iBarEnd++) { List <TargetFace> faces = new List <TargetFace>(); // get current Start/End constraint RebarConstraint constraint = (iBarEnd == 0) ? data.GetRebarUpdateCurvesData().GetStartConstraint() : data.GetRebarUpdateCurvesData().GetEndConstraint(); //if no constraint present, then search for a new one if (constraint == null) { if (hostFaces.Count <= 0)// fetch the faces of the structural used for searching constraints. { // used compute references to true to make sure we can create constraints with the faces we find Options geomOptions = new Options(); geomOptions.ComputeReferences = true; // the host structural is considered the first structural in the first constraint GeometryElement elemGeometry = data.GetRebarUpdateCurvesData().GetCustomConstraints()[0].GetTargetElement(0).get_Geometry(geomOptions); if (elemGeometry == null) { return(false); } hostFaces = getFacesFromElement(elemGeometry); } // for each bar try to find the closest face that intersects with it, or its extension, at the specified end for (int idx = 0; idx < allbars.Count; idx++) { faces.Add(searchForFace(allbars[idx], hostFaces, iBarEnd)); } // gather valid references for constraint creation List <Reference> refs = new List <Reference>(); foreach (TargetFace face in faces) { if (face.Face.Reference != null && !refs.Contains(face.Face.Reference)) { refs.Add(face.Face.Reference); } } // if we have any valid references, we create the constraint for the specified bar end. if (refs.Count > 0) { if (iBarEnd == 0) { data.CreateStartConstraint(refs, false, 0.0); } else { data.CreateEndConstraint(refs, false, 0.0); } } } else// if constraint is present, extract needed information to calculate trim/extend { for (int nTarget = 0; nTarget < constraint.NumberOfTargets; nTarget++) { var trf = Transform.Identity; Face constrainedFace = constraint.GetTargetHostFaceAndTransform(nTarget, trf); if (constrainedFace == null) { continue; } double dfOffset; if (getOffsetFromConstraintAtTarget(data.GetRebarUpdateCurvesData(), constraint, 0, out dfOffset)) { faces.Add(new TargetFace() { Face = constrainedFace, Transform = trf, Offset = dfOffset }); } } } // for each bar, find out where it intersects with the selected faces and replace the original curve with a new one that is shorter or longer. // first search for extension intersection (use tangent curve in the end point of the curve), then search for actual curve intersection for (int idx = 0; idx < allbars.Count; idx++) { XYZ intersection; Curve barCurve = allbars[idx]; if (!(barCurve is Line))// this code only deals with input curves that are straight lines { return(false); } Line tangent = Line.CreateUnbound(barCurve.GetEndPoint(iBarEnd), barCurve.ComputeDerivatives(iBarEnd, true).BasisX.Normalize() * (iBarEnd == 0 ? -1 : 1)); double dfOffset = 0.0; if (getIntersection(tangent, faces, out intersection, out dfOffset) || getIntersection(barCurve, faces, out intersection, out dfOffset)) { Curve newCurve = null; try { XYZ barDir = (barCurve.GetEndPoint(1) - barCurve.GetEndPoint(0)).Normalize(); if ((iBarEnd == 0)) { newCurve = Line.CreateBound(intersection - barDir * dfOffset, barCurve.GetEndPoint(1)); } else { newCurve = Line.CreateBound(barCurve.GetEndPoint(0), intersection + barDir * dfOffset); } } catch { } // if new curve available, replace the old one. if (newCurve != null) { allbars[idx] = newCurve; } } } } // get the FirstHandle constraint and extract the target face to use in determining the hook orientation for each bar TargetFace firstFace = new TargetFace(); IList <RebarConstraint> constraints = data.GetRebarUpdateCurvesData().GetCustomConstraints(); foreach (RebarConstraint constraint in constraints) { if ((BarHandle)constraint.GetCustomHandleTag() == BarHandle.FirstHandle) { Transform tempTrf = Transform.Identity; double dfOffset; if (!getOffsetFromConstraintAtTarget(data.GetRebarUpdateCurvesData(), constraint, 0, out dfOffset)) { return(false); } firstFace = new TargetFace() { Face = constraint.GetTargetHostFaceAndTransform(0, tempTrf), Transform = tempTrf, Offset = dfOffset }; break; } } // add each curve as separate bar in the set. for (int ii = 0; ii < allbars.Count; ii++) { List <Curve> barCurve = new List <Curve>(); barCurve.Add(allbars[ii]); data.AddBarGeometry(barCurve); // hook normals are reset when adding new bar geometry, so we need to // set the hook normals for each bar that was modified for (int i = 0; i < 2; i++) { XYZ normal = computeNormal(allbars[ii], firstFace, i); if (normal != null && !normal.IsZeroLength()) { data.GetRebarUpdateCurvesData().SetHookPlaneNormalForBarIdx(i, ii, normal); } } } return(true); }