步骤:
- 拾取面
- 拿到面的轮毂
- 最大的轮毂
- 洞口的轮廓
- 定位起铺点,定位第一块砖
- 以复制方式定位下 一块转,知道铺满
- 根据满铺的多边形,裁剪出面的跟面相交的轮毂
- 根据裁剪出来的轮毂,生成砖(常规模型)
关键技术点:
- 如何拿到面上的所有洞口:a、直接根据Face的CurveLoop去判断;b、如果面是墙,墙上有门、窗、矩形洞口,可以根据IFC的dll中有拿到墙上的洞口多边形
- 把面做为一个坐标系,放平后,根据二维几何运算,进行多边形的剪切与复制、移动的操作:这其中用到了g3,Clipper的两个库
- 如果是异形多边形生成常规模型,需要进行放样的方式创建常规模型
/// <summary> /// 多变形的合并剪切的关系 /// </summary> /// <param name="clipPolygon">裁剪的多边形</param> /// <param name="subPolygon">被裁剪的多边形</param> /// <param name="clipType"> ctIntersection = 0, 获取两者相交的部分;ctUnion = 1,获取两者并集部分;ctDifference = 2,获取Clip区域以外的区域, ctXor = 3 获取两个区域互不重复的区域</param> /// <returns></returns> public static List<List<IntPoint>> PolygonClipperUtils(List<IntPoint> clipPolygon, List<IntPoint> subPolygon, ClipType clipType = ClipType.ctIntersection) { if (m_clipper == null) m_clipper = new Clipper(); m_clipper.Clear(); m_clipper.AddPath(clipPolygon, PolyType.ptClip, true); m_clipper.AddPath(subPolygon, PolyType.ptSubject, true); List<List<IntPoint>> solution = new List<List<IntPoint>>(); bool b = m_clipper.Execute(clipType, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); return solution; } /// <summary> /// 获取当前面的的Transform(用于基于当前的面做直角坐标系) /// </summary> /// <param name="face"></param> /// <returns></returns> public static Transform PlanarFaceTransform(this PlanarFace face) { return TransformByVectors(XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ, XYZ.Zero, face.XVector, face.YVector, face.FaceNormal, face.Origin); } public static Transform PlaneTransform(this Plane plane) { return TransformByVectors(XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ, XYZ.Zero, plane.XVec, plane.YVec, plane.Normal, plane.Origin); } public static Transform TransformByVectors(XYZ oldX, XYZ oldY, XYZ oldZ, XYZ oldOrigin, XYZ newX, XYZ newY, XYZ newZ, XYZ newOrigin) { Transform transform = Transform.Identity; double xx = oldX.DotProduct(newX); double xy = oldX.DotProduct(newY); double xz = oldX.DotProduct(newZ); double yx = oldY.DotProduct(newX); double yy = oldY.DotProduct(newY); double yz = oldY.DotProduct(newZ); double zx = oldZ.DotProduct(newX); double zy = oldZ.DotProduct(newY); double zz = oldZ.DotProduct(newZ); transform.BasisX = new XYZ(xx, xy, xz); transform.BasisY = new XYZ(yx, yy, yz); transform.BasisZ = new XYZ(zx, zy, zz); XYZ translation = newOrigin - oldOrigin; double translationNewX = xx * translation.X + yz * translation.Y + zx * translation.Z; double translationNewY = yz * translation.X + yy * translation.Y + yz * translation.Z; double translationNewZ = zx * translation.X + zy * translation.Y + zz * translation.Z; transform.Origin = new XYZ(translationNewX, translationNewY, translationNewZ); return transform; }