revit几何信息如何存储?Revit 如何获取梁柱几何信息
Author-----Yen
Revit 如何获取梁柱几何信息
这个例子来源于Revit SDK samples中的NewRebar例子,例子中有一个GeometrySupport类,用于判断你选择的梁或者柱是否是正方形,这个类涉及到的知识点非常多,非常有趣,主要可以概况为:
1、获取梁柱的轮廓面Face信息
2、如何判断一个edge是否是一条线
3、如何进行局部全局的坐标变换
4、如何判断两个向量方向同向或者异向
5、如何判断一条线与面是否垂直
6、判断两个点是否相同
类GeometrySupport的主要逻辑:
public GeometrySupport(FamilyInstance element){// get the geometry element of the ed element// 获取元素的几何,判断是否存在几何元素Autodesk.Revit.DB.GeometryElement geoElement = element.get_Geometry(new Options());IEnumerator<GeometryObject> Objects = geoElement.GetEnumerator();if (null == geoElement || !Objects.MoveNext()){throw new Exception("Can't get the geometry of ed element.");}// 获取元素的轮廓信息SweptProfile swProfile = element.GetSweptProfile();// 判断路径是否是直线if (swProfile == null || !(swProfile.GetDrivingCurve() is Line)){throw new Exception("The ed element driving curve is not a line.");}// get the driving path and vector of the beam or columnLine line = swProfile.GetDrivingCurve() as Line;if (null != line){m_drivingLine = line; // driving path 路径// 根据两个点求一个方向向量,末尾点减去初始点m_drivingVector = GeomUtil.SubXYZ(line.GetEndPoint(1), line.GetEndPoint(0));m_drivingLength = m_drivingVector.GetLength();}//get the geometry object//foreach (GeometryObject geoObject in geoElement.Objects)Objects.Reset();while (Objects.MoveNext()){GeometryObject geoObject = Objects.Current;//get the geometry instance which contains the geometry informationGeoInstance instance = geoObject as GeoInstance;if (null != instance){//foreach (GeometryObject o in instance.SymbolGeometry.Objects)// 都是从SymbolGeometry这个属性拿到具体的几何对象IEnumerator<GeometryObject> Objects1 = instance.SymbolGeometry.GetEnumerator();while (Objects1.MoveNext()){GeometryObject o = Objects1.Current;// get the solid of beam of columnSolid solid = o as Solid;// do some checks.if (null == solid){continue;}if (0 == solid.Faces.Size || 0 == solid.Edges.Size){continue;}m_solid = solid;//get the transform value of instance// 这个是GeometryObject的局部坐标系的转换矩阵m_transform = instance.Transform;// Get the swept profile curves information// 获取轮廓信息if (!GetSweptProfile(solid)){throw new Exception("Can't get the swept profile curves.");}break;}}}// do some checks about profile curves informationif (null == m_edges){throw new Exception("Can't get the geometry edge information.");}// 通过四个点个数来判断是否是方形if (4 != m_points.Count){throw new Exception("The sample only works for rectangle beam or column.");}}
如何获取拉伸的轮廓信息:
主要是根据传入的solid信息来获取拉伸面Face的信息
private Face GetSweptProfileFace(Solid solid){// Get a point on the swept profile from all points in solidAutodesk.Revit.DB.XYZ refPoint = new Autodesk.Revit.DB.XYZ(); // the point on swept profile// 遍历solid的每一条边edgeforeach (Edge edge in solid.Edges){// 如果判断edge是一条线,先离散,再判断点个数是否是2个List<XYZ> points = edge.Tessellate() as List<XYZ>; //get end points of the edgeif (2 != points.Count) // make sure all edges are lines{throw new Exception("Each edge should be a line.");}// get two points of the edge. All points in solid should be transformed firstAutodesk.Revit.DB.XYZ first = Transform(points[0]); // start point of edgeAutodesk.Revit.DB.XYZ second = Transform(points[1]); // end point of edge// some edges should be paralleled with the driving line,// and the start point of that edge should be the wanted pointAutodesk.Revit.DB.XYZ edgeVector = GeomUtil.SubXYZ(second, first);// 判断是否与路径的方向一致,进而取到轮廓面上的点if (GeomUtil.IsSameDirection(edgeVector, m_drivingVector)){refPoint = first;break;}if (GeomUtil.IsOppositeDirection(edgeVector, m_drivingVector)){refPoint = second;break;}}// Find swept profile(face)Face sweptFace = null; // define the swept faceforeach (Face face in solid.Faces){if (null != sweptFace){break;}// the swept face should be perpendicular with the driving line// 面是否垂直于路径线if (!GeomUtil.IsVertical(face, m_drivingLine, m_transform, null)){continue;}// use the point to get the swept face// 获取面的三角化后的顶点数据foreach (Autodesk.Revit.DB.XYZ point in face.Triangulate().Vertices){Autodesk.Revit.DB.XYZ pnt = Transform(point); // all points in solid should be transformed// 判断点是否相同if (GeomUtil.IsEqual(refPoint, pnt)){sweptFace = face;break;}}}return sweptFace;}
如何从局部坐标系转换到全局坐标系:
public static Autodesk.Revit.DB.XYZ TransformPoint(Autodesk.Revit.DB.XYZ point, Transform transform){//get the coordinate value in X, Y, Z axis// 要转换点的XYZ坐标值double x = point.X;double y = point.Y;double z = point.Z;//transform basis of the old coordinate system in the new coordinate system// API中没有具体说明get_Basis,猜想对应的是BasisX,BasisY,BasisZ,也就是矩阵的第1,2,3列元素Autodesk.Revit.DB.XYZ b0 = transform.get_Basis(0);Autodesk.Revit.DB.XYZ b1 = transform.get_Basis(1);Autodesk.Revit.DB.XYZ b2 = transform.get_Basis(2);Autodesk.Revit.DB.XYZ origin = transform.Origin;//transform the origin of the old coordinate system in the new coordinate system// 矩阵相乘,并考虑原点的偏移double xTemp = x * b0.X + y * b1.X + z * b2.X + origin.X;double yTemp = x * b0.Y + y * b1.Y + z * b2.Y + origin.Y;double zTemp = x * b0.Z + y * b1.Z + z * b2.Z + origin.Z;return new Autodesk.Revit.DB.XYZ (xTemp, yTemp, zTemp);}
如何判断两个向量方向同向或者异向
public static bool IsSameDirection(Autodesk.Revit.DB.XYZ firstVec, Autodesk.Revit.DB.XYZ secondVec){// get the unit vector for two vectors// 获取单位向量Autodesk.Revit.DB.XYZ first = UnitVector(firstVec);Autodesk.Revit.DB.XYZ second = UnitVector(secondVec);// if the dot product of two unit vectors is equal to 1, return true// 点乘后是否等于1,等于1就是同向double dot = DotMatrix(first, second);return (IsEqual(dot, 1));}public static bool IsOppositeDirection(Autodesk.Revit.DB.XYZ firstVec, Autodesk.Revit.DB.XYZ secondVec){// get the unit vector for two vectorsAutodesk.Revit.DB.XYZ first = UnitVector(firstVec);Autodesk.Revit.DB.XYZ second = UnitVector(secondVec);// if the dot product of two unit vectors is equal to -1, return true// 点乘后是否等于-1,等于-1就是异向double dot = DotMatrix(first, second);return (IsEqual(dot, -1));}
如何判断线是否垂直于面
public static bool IsVertical(Face face, Line line, Transform faceTrans, Transform lineTrans){//get points which the face contains// 获取面的三角化的顶点坐标List<XYZ> points = face.Triangulate().Vertices as List<XYZ>;if (3 > points.Count) // face's point number should be above 2{return false;}// get three points from the face pointsAutodesk.Revit.DB.XYZ first = points[0];Autodesk.Revit.DB.XYZ second = points[1];Autodesk.Revit.DB.XYZ third = points[2];// get start and end point of lineAutodesk.Revit.DB.XYZ lineStart = line.GetEndPoint(0);Autodesk.Revit.DB.XYZ lineEnd = line.GetEndPoint(1);// transForm the three points if necessary// 坐标转换if (null != faceTrans){first = TransformPoint(first, faceTrans);second = TransformPoint(second, faceTrans);third = TransformPoint(third, faceTrans);}// transform the start and end points if necessaryif (null != lineTrans){lineStart = TransformPoint(lineStart, lineTrans);lineEnd = TransformPoint(lineEnd, lineTrans);}// form two vectors from the face and a vector stand for the line// Use SubXYZ() method to get the vectorsAutodesk.Revit.DB.XYZ vector1 = SubXYZ(first, second); // first vector of faceAutodesk.Revit.DB.XYZ vector2 = SubXYZ(first, third); // second vector of faceAutodesk.Revit.DB.XYZ vector3 = SubXYZ(lineStart, lineEnd); // line vector// get two dot products of the face vectors and line vector// 计算面的两个向量和线的向量的点积double result1 = DotMatrix(vector1, vector3);double result2 = DotMatrix(vector2, vector3);// if two dot products are all zero, the line is perpendicular to the face// 如果两个点积是0的话,线就是垂直于面return (IsEqual(result1, 0) && IsEqual(result2, 0));}
判断两个点是否相同
public static bool IsEqual(Autodesk.Revit.DB.XYZ first, Autodesk.Revit.DB.XYZ second){bool flag = true;// 每一个点都相同就是相等flag = flag && IsEqual(first.X, second.X);flag = flag && IsEqual(first.Y, second.Y);flag = flag && IsEqual(first.Z, second.Z);return flag;}// 相等用减法,差值小于一个非常小的数public static bool IsEqual(double d1, double d2){//get the absolute value;double diff = Math.Abs(d1 - d2);// const double Precision = 0.00001;// precision when judge whether two doubles are equalreturn diff < Precision;}
BIM技术是未来的趋势,学习、了解掌握更多BIM前言技术是大势所趋,欢迎更多BIMer加入BIM中文网大家庭(http://www.wanbim.com),一起共同探讨学习BIM技术,了解BIM应用!
相关培训