Create dimension line for rebar

Create dimension line for rebar

Anonymous
Not applicable
4,540 Views
7 Replies
Message 1 of 8

Create dimension line for rebar

Anonymous
Not applicable

Hi All,

 

I'm struggling to create a rebar dimension line because I can't find a way to get the edges of the element in a Section View (see picture below).

 

image.png

I could get the edge through their geometry, but this object (edge) doesn't have a "reference" to call.

 

Do you have some suggestions here? Any tip of advice will be well received.

 

Thanks in advance!

0 Likes
Accepted solutions (1)
4,541 Views
7 Replies
Replies (7)
Message 2 of 8

Anonymous
Not applicable

PS: I'm trying to create a dimension line to get the following situation. to measure how far is the end of the bar from a level/grid.

image.png

0 Likes
Message 3 of 8

lloyolaRLE
Participant
Participant

I had the same problem...still have it. Any help, or walk around, would be great!  

0 Likes
Message 4 of 8

zhong_wu
Autodesk Support
Autodesk Support

Hi Jorge, 

 

I just searched from the forum, and I found the similar question and solution as follow:

 

You can read the geometry data from the rebar by Rebar.Geometry property. This property requires an Option argument. you need to set the option.ComputeReferences to true. Then read the edge of the rebar, and get the curve from the Edge object. Finally get the end point reference from the curve.

 

The original discussions can be found at:

https://forums.autodesk.com/t5/revit-api-forum/dimension-rebars/td-p/5356233  

https://forums.autodesk.com/t5/revit-api-forum/create-aligned-dimension-between-rebars/m-p/7083248/h...

 

Hope this helps;)


John Wu
Developer Technical Services
Autodesk Developer Network


0 Likes
Message 5 of 8

Anonymous
Not applicable

Hi @zhong_wu, thanks for the response.

 

I already looked at these posts but with no results. When I create the dimension line, a reference is needed. Using: "Then read the edge of the rebar and get the curve from the Edge object. Finally get the end point reference from the curve", when getting a reference from the edge I get "Null".  

 

Here are 4 different paths I took with no desired result:

 

##### PLAN A #####

ReferenceArray ra = new ReferenceArray();
Line dimension = Line.CreateBound(rebar_top, apoyo_top);
DetailLine line1 = doc.Create.NewDetailCurve(view, dimension) as DetailLine;
ra.Append(line1.GeometryCurve.GetEndPointReference(1));
ra.Append(line1.GeometryCurve.GetEndPointReference(0));                                           
Dimension dim = doc.Create.NewDimension(doc.ActiveView, dimension, ra);


##### PLAN B #####

XYZ apoyo_top = pAnalisisSupCap + rle.cm_to_ft(200) * XYZ.BasisZ;
XYZ apoyo_bot = pAnalisisSupCap - rle.cm_to_ft(200) * XYZ.BasisZ;
XYZ rebar_top = pini + rle.cm_to_ft(200) * XYZ.BasisZ;
XYZ rebar_bot = pini - rle.cm_to_ft(200) * XYZ.BasisZ;
Line l_v = Line.CreateBound(apoyo_bot, apoyo_top);
Line l_h = Line.CreateBound(rebar_bot, rebar_top);

//SketchPlane skplane = SketchPlane.Create(doc, plano_vista);
Plane p_h = Plane.CreateByNormalAndOrigin(rebar_bot.CrossProduct(rebar_top), rebar_top);

//Plane p_h = Plane.CreateByNormalAndOrigin();
SketchPlane skplane_h = SketchPlane.Create(doc, p_h);

Plane p_v = Plane.CreateByNormalAndOrigin(apoyo_bot.CrossProduct(apoyo_top), apoyo_top);
SketchPlane skplane_v = SketchPlane.Create(doc, p_v);

ModelCurve modelcurve1 = doc.Create.NewModelCurve (l_h, skplane_h);
ModelCurve modelcurve2 = doc.Create.NewModelCurve(l_v, skplane_v);
 
ra.Append(modelcurve1.GeometryCurve.Reference);
ra.Append(modelcurve2.GeometryCurve.Reference);
ra.Append(modelcurve1.GeometryCurve.GetEndPointReference(0));
ra.Append(modelcurve2.GeometryCurve.GetEndPointReference(0));
											
##### PLAN C ##### 

Options opt = new Options();
opt.ComputeReferences = true;
opt.View = doc.ActiveView;
opt.IncludeNonVisibleObjects = true;
//opt.DetailLevel = ViewDetailLevel.Fine;

//GeometryElement geomElem = nvrant.getElemento().get_Geometry(opt); // VIGA entrega faces
GeometryElement geomElem = rebInt.get_Geometry(opt);
//GeometryElement geomElem = rebInt.GetFullGeometryForView(doc.ActiveView);
											
foreach (GeometryObject geomObj in geomElem)

{
	Solid geomSolid = geomObj as Solid;
	

	if (null != geomSolid)
	{
		int faces = 0;
		double totalArea = 0;
		foreach (Face geomFace in geomSolid.Faces)
		{
			faces++;
			faceInfo += "Face " + faces + " area: " + geomFace.Area.ToString() + "\n";
			totalArea += geomFace.Area;
			info = geomFace;
		}
		faceInfo += "Number of faces: " + faces + "\n";
		faceInfo += "Total area: " + totalArea.ToString() + "\n";

		int edge = 0;
		foreach (Edge geomEdge in geomSolid.Edges)
		{
			// get wall's geometry edges
			//if (edge == 0)
		   // {
				geoobj = geomEdge.AsCurve();
			// }
			// edge++;
			// faceInfo += "Edge " + edge +  "\n";

			
		   // Reference r1 = geoobj.GetEndPointReference(1);
		   // shapeHandlePoints.
		}
	}
}
// No Faces/Edges valiuds as references.
											
##### PLAN D ##### 
IList<RebarConstrainedHandle> dd = rebInt.GetRebarConstraintsManager().GetAllHandles();

RebarConstrainedHandle s = null;
RebarConstrainedHandle e = null;
foreach (RebarConstrainedHandle rbh in dd)
{
	if (rbh.GetHandleName().ToString() == "Start of Bar")
	{
		s = rbh;
	}
	if (rbh.GetHandleName().ToString() == "End of Bar")
	{
		e = rbh;
	}
}
// This objects (handles) doesn't give references.

What am I missing here?

 

Regards!

 

 

0 Likes
Message 6 of 8

zhong_wu
Autodesk Support
Autodesk Support

I use similar code and verified with your plan A, there is an exception saying "The direction of dimension is invalid", the reason is the input value "dimension" should be inside the plan of doc.ActiveView. So I changed the input value dimension of the following code line to line1.GeometryCurve as Line, it works, but you just need to offset Z of the dimension line to make it looks good. 

 

Dimension dim = doc.Create.NewDimension(doc.ActiveView, dimension line1.GeometryCurve as Line, ra);

 Let me know if it works for you.


John Wu
Developer Technical Services
Autodesk Developer Network


0 Likes
Message 7 of 8

zhong_wu
Autodesk Support
Autodesk Support
Accepted solution

With the great support from our Revit engineer, I got the solution and verified, it works fine to dimension between rebar and grid.

 

The code contains a command that place a dimension in your model. You will need to select the rebar. The grid line is hard-coded by id.


It implemented the following idea: Get all rebar references and filter them (choose the only one that we need). Get the grid reference. With the rebar ref and grid ref create the dimension.

 

If you want to only dimension the rebar, you just need to change the code to get the 2 reference of edges which are perpendicular with rebarSeg, hope it helps:

using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB.Structure;

namespace TestRebar
{
   [TransactionAttribute(TransactionMode.Manual)]
   [RegenerationAttribute(RegenerationOption.Manual)]
   public class TestRebar : IExternalCommand
   {
      UIApplication m_uiApp;
      Document m_doc;

      ElementId elementId = ElementId.InvalidElementId;

      public Result Execute(
        ExternalCommandData commandData,
        ref string message,
        ElementSet elements)
      {
         try
         {
            initStuff(commandData);
            if (m_doc == null)
               return Result.Failed;

            m_uiApp = commandData.Application;
            Selection sel = m_uiApp.ActiveUIDocument.Selection;
            Reference refr = sel.PickObject(ObjectType.Element);
          
            Rebar rebar = m_doc.GetElement(refr.ElementId) as Rebar;

            Line rebarSeg = null;
            bool bOk = getRebarSegment(rebar, out rebarSeg);
            if (!bOk)
               return Result.Failed;

            Options options = new Options();
            options.View = m_uiApp.ActiveUIDocument.ActiveView; // the view in which you want to place the dimension
            options.ComputeReferences = true; // This will produce the references
            options.IncludeNonVisibleObjects = true;
            GeometryElement wholeRebarGeometry = rebar.get_Geometry(options);
            Reference refForEndOfBar = getReferenceForEndOfBar(wholeRebarGeometry, rebarSeg);


            Reference refGrid = getGridRef();

            ReferenceArray refArray = new ReferenceArray();
            refArray.Append(refForEndOfBar);
            refArray.Append(refGrid);

            double dist = 10;

            Line dimLine = rebarSeg.CreateOffset(dist, XYZ.BasisY) as Line; // a line parallel with our rebar segment somewhere in the space.

            using (Transaction tr = new Transaction(m_doc, "Create Dimension"))
            {
               tr.Start();
               m_doc.Create.NewDimension(m_uiApp.ActiveUIDocument.ActiveView, dimLine, refArray);
               tr.Commit();
            }
         }
         catch (Exception e)
         {
            TaskDialog.Show("exception", e.Message);
            return Result.Failed;
         }

         return Result.Succeeded;
      }

      private Reference getGridRef()
      {
         ElementId idGrd = new ElementId(397028);
         Element elemGrid = m_doc.GetElement(idGrd);
         Options options = new Options();
         options.View = m_uiApp.ActiveUIDocument.ActiveView; // the view in which you want to place the dimension
         options.ComputeReferences = true; // This will produce the references
         options.IncludeNonVisibleObjects = true;
         GeometryElement wholeGridGeometry = elemGrid.get_Geometry(options);
         IList<Reference> allRefs = new List<Reference>();
         foreach (GeometryObject geomObj in wholeGridGeometry)
         {
            Line refLine = geomObj as Line;
            if (refLine != null && refLine.Reference != null)
               return refLine.Reference;
         }

         return null; 
      }

      private Reference getReferenceForEndOfBar(GeometryElement geom, Line rebarSeg)
      {
         foreach (GeometryObject geomObj in geom)
         {
            Solid sld = geomObj as Solid;
            if (sld != null)
            {
               // I'll get the references from curves;
               continue;
            }
            else
            {
               Line refLine = geomObj as Line;
               if (refLine != null && refLine.Reference !=null)
               {
                  // We found one reference. Let's see if it is the correct one. 
                  // The correct referece need to be perpendicular to rebar segement and the end point of rebar segment should be on the reference curve.
                  double dotProd = refLine.Direction.DotProduct(rebarSeg.Direction);
                  if (Math.Abs(dotProd) != 0) 
                     continue; // curves are not perpendicular.

                  XYZ endPointOfRebar = rebarSeg.GetEndPoint(1);
                  IntersectionResult ir = refLine.Project(endPointOfRebar);
                  if (ir == null)
                     continue; // end point of rebar segment is not on the reference curve.

                  if (Math.Abs(ir.Distance) != 0)
                     continue; // end point of rebar segment is not on the reference curve.

                  return refLine.Reference;
               }
            }
         }
         return null;
      }

      private bool getRebarSegment(Rebar rebar, out Line rebarSeg)
      {
         rebarSeg = null;
         IList<Curve> rebarSegments = rebar.GetCenterlineCurves(false, true, true, MultiplanarOption.IncludeOnlyPlanarCurves, 0);
         if (rebarSegments.Count != 1)
            return false;

         rebarSeg = rebarSegments[0] as Line;
         if (rebarSeg == null)
            return false;

         return true;
      }

      void initStuff(ExternalCommandData commandData)
      {
         m_uiApp = commandData.Application;
         m_doc = m_uiApp.ActiveUIDocument.Document;
      }
   }
}




  


John Wu
Developer Technical Services
Autodesk Developer Network


Message 8 of 8

Anonymous
Not applicable

Dear Zhon Wu,

 

Thanks a lot for the response. It is the solution to our problem! We made little adjustments to the code to have plenty of control about what end do we want to dimension and also we had to project all the curves involved in a shared reference plane due that if you have more than one rebar (rebar set) the geometry of the rebar is above or beneath the grid line.

 

Again, thanks a lot for your time and effort.

 

Kind regards!

0 Likes