Proplem with creating dimensions based on objects from linked files

Proplem with creating dimensions based on objects from linked files

Kisli89
Enthusiast Enthusiast
1,528 Views
5 Replies
Message 1 of 6

Proplem with creating dimensions based on objects from linked files

Kisli89
Enthusiast
Enthusiast

The topic http://thebuildingcoder.typepad.com/blog/2014/07/createlinkreference-sample-code.html#2 discussed how to get a "Reference" for objects from linked files and use them further to create objects based on faces. I decided to create dimensions and submitted to the method of creating the "ReferenceArray" from the linked file, but I get the error "invalid number of references".

 

List<RevitLinkInstance> linkDocument = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)).Cast<RevitLinkInstance>().ToList();
string data = "";
DocumentSet doklIst = app.Documents;

List<Document> LinkDokInThisFile = new List<Document>();
foreach (Document dd in doklIst) {
    if (dd.IsLinked) {
        LinkDokInThisFile.Add(dd);
    }
}
List<Dimenser> wallListX = new List<Dimenser>();
List<Dimenser> wallListY = new List<Dimenser>();
if (linkDocument.Count > 0) {
    foreach (RevitLinkInstance ins in linkDocument) {
        var collect = new FilteredElementCollector(ins.GetLinkDocument()).OfClass(typeof(Wall)).ToElements();
        foreach (Wall w in collect) {
            Dimenser z = new Dimenser(ins.GetLinkDocument(), w, opt, ins, false);
            if (Math.Round(z.DirectionX, 4) != 0) wallListX.Add(z);
            else wallListY.Add(z);
        }
    }
}
 Transform trans = wallListX[0].LincInstance.GetTransform();
 var p1 = trans.OfPoint(wallListX[0].MidPoint);
 var p2 = trans.OfPoint(wallListX[0].MidPoint1);  
var MidLine = Line.CreateBound(p1, p2);
ReferenceArray ra = new ReferenceArray();
foreach (Dimenser dim in wallListX) {
    Reference rr = null;
    Reference rr2 = null;
    if (dim.LincInstance != null) {
        rr = dim.Face[0].Reference.CreateLinkReference(dim.LincInstance);
        rr2 = dim.Face[1].Reference.CreateLinkReference(dim.LincInstance);
    }
    else {
        rr = dim.Face[0].Reference;
        rr2 = dim.Face[1].Reference;
    }                 
    ra.Append(rr);
    ra.Append(rr2);
}
Dimension dimens = doc.Create.NewDimension(doc.ActiveView, MidLine, ra);

  public class Dimenser
    {
        ReferenceArray refa = new ReferenceArray();
        public XYZ Direction { get; set; }
        public Document Document { get; set; }
        public RevitLinkInstance LincInstance { get; set; }
        public double Thinknes { get; set; }
        public double DirectionX { get; set; }
        public double DirectionY { get; set; }
        public XYZ MidPoint1 { get; set; }
        public XYZ MidPoint { get; set; }
        public Line MidLine { get; set; }
        public List<PlanarFace> Face { get; set; } = new List<PlanarFace>();
        public Wall Wall { get; set; }
        public Line GeoLine { get; set; }
        public double Height { get; set; }
        public ReferenceArray Endrefa { get; set; } = new ReferenceArray();
        public List<PlanarFace> EndFace { get; set; } = new List<PlanarFace>();
        public ElementId ElemId { get; }
        public Dimenser(Document doc, Element wall, Options opt, RevitLinkInstance lincInst, bool forHoll) {
            Document = doc;
            LincInstance = lincInst;
            WallType ty = (WallType)doc.GetElement(wall.GetTypeId());
            foreach (Parameter par in ty.Parameters) {
                if (par.Definition.Name == "Ширина" || par.Definition.Name == "Width")
                    Thinknes = par.AsDouble();

                
            }
            foreach (Parameter par in wall.Parameters)
            {
                if (par.Definition.Name == "Неприсоединенная высота" || par.Definition.Name == "Unconnected Height")
                    this.Height = par.AsDouble();
            }
          
            this.Wall = (Wall)wall;
            this.ElemId = Wall.Id;
            LocationCurve geoCurve = wall.Location as LocationCurve;
            GeoLine = (geoCurve.Curve) as Line;
            this.DirectionX = Round(GeoLine.Direction.Y, 4);
            this.DirectionY = Round(GeoLine.Direction.X, 4);
            Direction = GeoLine.Direction;
            XYZ p = Midpoint(GeoLine);
            MidPoint = new XYZ((p.X + (Thinknes / 2) * DirectionX), (p.Y + (Thinknes / 2) * DirectionY), p.Z + Height / 2);
            MidPoint1 = new XYZ((p.X - (Thinknes / 2) * DirectionX), (p.Y - (Thinknes / 2) * DirectionY), p.Z + Height / 2);
            MidLine = Line.CreateBound(MidPoint, MidPoint1);
            List<PlanarFace> pf = GetFacesAndEdges(wall, opt);
            foreach (PlanarFace element in pf) {
                if ((Abs(Round(element.XVector.X, 4)) == Abs(Round(GeoLine.Direction.X, 4))
                && Abs(Round(element.XVector.Y, 4)) == Abs(Round(GeoLine.Direction.Y, 4))
                 && Abs(Round(element.FaceNormal.Z, 4)) == 0)) {
                    Face.Add(element);
                    Reference re = element.Reference;
                    refa.Append(re);
                }
                if ((Abs(Round(element.XVector.X, 4)) == Abs(Round(GeoLine.Direction.Y, 4))
                && Abs(Round(element.XVector.Y, 4)) == Abs(Round(GeoLine.Direction.X, 4))
                && Abs(Round(element.FaceNormal.Z, 4)) == 0)) {
                    if (forHoll == false) {
                        Line L = LineFromFace(element);
                        string poin = Round(Midpoint(L).X, 4)  + Round(Midpoint(L).Y, 4).ToString();
                        string P2 = Round(GeoLine.GetEndPoint(0).X, 4)  + Round(GeoLine.GetEndPoint(0).Y, 4).ToString();
                        string P3 = Round(GeoLine.GetEndPoint(1).X, 4)  + Round(GeoLine.GetEndPoint(1).Y, 4).ToString();
                        if (poin == P2 || poin == P3) {
                            GeometryObject f = element as GeometryObject;
                            EndFace.Add(element);
                        }
                    }
                    else {
                        Line L = LineFromFace(element);
                        string poin = Round(Midpoint(L).X, 1)  + Round(Midpoint(L).Y, 1).ToString();
                        string P2 = Round(GeoLine.GetEndPoint(0).X, 1)  + Round(GeoLine.GetEndPoint(0).Y, 1).ToString();
                        string P3 = Round(GeoLine.GetEndPoint(1).X, 1)  + Round(GeoLine.GetEndPoint(1).Y, 1).ToString();

                        if (poin != P2 && poin != P3) {
                            GeometryObject f = element as GeometryObject;
                            EndFace.Add(element);
                        }
                    }
                }
            }
        }
        public Dimenser(Document doc, Element wall, Options opt) {
            WallType ty = (WallType)doc.GetElement(wall.GetTypeId());
            foreach (Parameter par in ty.Parameters) {
                if (par.Definition.Name == "Ширина" || par.Definition.Name == "Width")
                    Thinknes = par.AsDouble();


            }
            foreach (Parameter par in wall.Parameters) {
                if (par.Definition.Name == "Неприсоединенная высота" || par.Definition.Name == "Unconnected Height")
                    this.Height = par.AsDouble();
            }
            this.Wall = (Wall)wall;
            this.ElemId = Wall.Id;
            LocationCurve geoCurve = wall.Location as LocationCurve;
            GeoLine = (geoCurve.Curve) as Line;
            this.DirectionX = Round(GeoLine.Direction.Y, 4);
            this.DirectionY = Round(GeoLine.Direction.X, 4);
            XYZ p = Midpoint(GeoLine);
            MidPoint = new XYZ((p.X + (Thinknes / 2) * DirectionX), (p.Y + (Thinknes / 2) * DirectionY), p.Z + Height / 2);
            MidPoint1 = new XYZ((p.X - (Thinknes / 2) * DirectionX), (p.Y - (Thinknes / 2) * DirectionY), p.Z + Height / 2);
            MidLine = Line.CreateBound(MidPoint, MidPoint1);
            List<PlanarFace> pf = GetFacesAndEdges(wall, opt);
            foreach (PlanarFace element in pf) {
                if ((Abs(Round(element.XVector.X, 4)) == Abs(Round(GeoLine.Direction.X, 4))
                && Abs(Round(element.XVector.Y, 4)) == Abs(Round(GeoLine.Direction.Y, 4))
                 && Abs(Round(element.FaceNormal.Z, 4)) == 0)) {
                    Face.Add(element);
                    Reference re = element.Reference;
                    refa.Append(re);
                }
                if ((Abs(Round(element.XVector.X, 4)) == Abs(Round(GeoLine.Direction.Y, 4))
                && Abs(Round(element.XVector.Y, 4)) == Abs(Round(GeoLine.Direction.X, 4))
                && Abs(Round(element.FaceNormal.Z, 4)) == 0)) {
                    GeometryObject f = element as GeometryObject;
                    EndFace.Add(element);
                }
            }
        }
       
    }
1,529 Views
5 Replies
Replies (5)
Message 2 of 6

pnunezcalzado
Participant
Participant

I have the same problem. References created by "CreateLinkReference" method doesn't work with "NewDimension" method. The error is "InvalidOperationException: Invalid number of references". How can we create a dimension between walls inside a revit link?

0 Likes
Message 3 of 6

Kisli89
Enthusiast
Enthusiast
Message 4 of 6

pnunezcalzado
Participant
Participant

Thanks for your answer Kisli! I knew this, post but it seemed "too much" in order to do a dimension.

Eventually, I have solved the problem through the reference intersector. The references inside links provided by the reference intersector are allowed in the dimension creation.

 

It´s good to know that it would have worked, and maybe I will do the experiment to compare the speed of each approximation (the reference intersector is not so good at that).

Message 5 of 6

joshua.lumley
Advocate
Advocate

It is simple: You have to rearrange the string a little to match the format:
"fb332d47-8286-4829-bd40-46c26de8ebac-000258d5:0:RVTLINK:2796184:1:SURFACE/5"

 

NOT

 

"fb332d47-8286-4829-bd40-46c26de8ebac-000258d5:RVTLINK/fb332d47-8286-4829-bd40-46c26de8ebac-000258d4:2796184:1:SURFACE/5"

 

 

            myCeiling = linkedDoc.GetElement(new ElementId(2796176)) as Ceiling;

            Reference top = HostObjectUtils.GetBottomFaces(myCeiling).First();
            if (inLinked) top = top.CreateLinkReference(myRevitLinkInstance);

            string myConvertToStableRepresentation = top.ConvertToStableRepresentation(doc);


            ReferenceArray _resArr = new ReferenceArray();
            //  List<Reference> myListReference = new List<Reference>();


            for (int ip = 0; ip < 2; ip++)
            {
                int index = 1 + (ip * /*_gridCount*/2 * 2);
                //string myCTSRwith = myConvertToStableRepresentation + string.Format("/{0}", index);


                List<string> myListString = myConvertToStableRepresentation.Split(new char[] { ':' }).ToList();
                int lenLST = myListString.Count;

                string myCTSRwith = myListString[0] + ":0:RVTLINK:" + myListString[lenLST - 3] + ":" + myListString[lenLST - 2] + ":" + myListString[lenLST - 1] + string.Format("/{0}", index);

                Reference HatchRef = null;
                try
                {
               
                    HatchRef = Reference.ParseFromStableRepresentation(doc, myCTSRwith);

                }
                catch
                { }
                if (HatchRef == null) continue;
                _resArr.Append(HatchRef);

            }
Message 6 of 6

jvideiraGZHPC
Participant
Participant

Hey @joshua.lumley ,
I tried formatting the string to the format you suggested, but I converted the string like this:

string myCTSRwith2 = myListString[0] + ":0:RVTLINK:" + myListString[lenLST - 3] + ":" + myListString[lenLST - 2] + ":" + myListString[lenLST - 1] + "/5";
And it didn't work


Why did you use a for loop to do this conversion?