一个客户问在Revit 2011上如何获得一个墙的侧面,而且把侧面坐标转到XOY平面在墙面上的坐标系。 对于同一个墙(长宽高相同), 任意旋转墙至不同的角度,获取的坐标值是相同的。
我的一篇博客也提到Revit 2012 提供的HostObjUtils类的方法,可以用HostObjUtils.GetSideFaces() 来快速获取侧面。 Revit 2011 没有提供HostObjUtils 类,所以只能是逐个遍历墙上的几何体,面,线。 这个方法在2012,2013仍然适用,不过需要写更多的代码。
下面是完整的一个例子获取选定的墙的侧面,并且获取这个面上的Edge的在XOY是墙面的坐标系下的向量。 另一个看点是如何做坐标转换,演示了如何使用Transform类。
下面是VB代码,这段代码只能针对直线型的墙。 - [vb] view plaincopy
- Imports Autodesk.Revit.DB
- Imports Autodesk.Revit.UI
- Imports Autodesk.Revit.Attributes
- Imports Autodesk.Revit.ApplicationServices
- Imports Autodesk.Revit.UI.Selection
-
- <TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)>
- Public Class CommandName
- Implements IExternalCommand
-
- Public Function Execute(ByVal commandData As ExternalCommandData, ByRef message As String, ByVal elements As ElementSet) As Result Implements IExternalCommand.Execute
- Dim doc As Document
- doc = commandData.Application.ActiveUIDocument.Document
- 'Pick a wall
-
- Dim sel As Selection = commandData.Application.ActiveUIDocument.Selection
- Dim ref1 As Reference = sel.PickObject(ObjectType.Element, "Please pick a wall to get its side face")
- Dim wall As Wall = ref1.Element
-
- Dim opt As Options = New Options()
- opt.View = doc.ActiveView
-
- Dim obj As GeometryObject
- Dim solid As Solid
- Dim face As Face
- Dim planF As PlanarFace
-
- Dim wallDirection As XYZ
- Dim LocationCurve As LocationCurve = wall.Location
- Dim line As Line = TryCast(LocationCurve.Curve, Line)
- If (line Is Nothing) Then
- Return Result.Failed
- End If
- wallDirection = line.EndPoint(0) - line.EndPoint(1)
-
- Dim sideFace As PlanarFace
-
- Dim transf As Transform
- 'Form a transform, to translate it to the face to the XOY.
- transf = Transform.Identity
- transf.BasisX = wallDirection.Normalize()
- transf.BasisY = wall.Orientation.Normalize()
- transf.BasisZ = transf.BasisX.CrossProduct(transf.BasisY)
-
- Dim ptResult1 As XYZ
- Dim ptResult2 As XYZ
- Dim pt As XYZ
- Dim ptString As String = Nothing
-
- For Each obj In wall.Geometry(opt).Objects
- If (TypeOf (obj) Is Solid) Then
- solid = TryCast(obj, Solid)
- 'Go through each face
- For Each face In solid.Faces
- planF = TryCast(face, PlanarFace)
- If (Not (planF Is Nothing)) Then
- If (planF.Normal.DotProduct(wallDirection) < 0.0001 And Math.Sin(planF.Normal.AngleTo(wall.Orientation)) < 0.001) Then
- 'get the side face.
- sideFace = planF
- transf.Origin = sideFace.Origin
- 'now you can convert the points in the sdie face to the user coordiantes. the result is like it.
- For Each edArr As EdgeArray In sideFace.EdgeLoops
- For Each ed As Edge In edArr
- pt = ed.Tessellate()(0)
- ptResult1 = transf.OfPoint(pt)
- pt = ed.Tessellate()(ed.Tessellate().Count - 1)
- ptResult2 = transf.OfPoint(pt)
- ptString += (ptResult1 - ptResult2).X.ToString() + " ; " + (ptResult1 - ptResult2).Y.ToString() + " ; " + (ptResult1 - ptResult2).Z.ToString() + vbCrLf
-
- Next
- Next
- End If
- End If
- Next
- End If
- Next
-
- TaskDialog.Show("pts", ptString)
-
- Return Result.Succeeded
- End Function
- End Class
复制代码 显示的结果如下。可以看到墙的角度不同,但是得到的结果是完全一样的。
作者:叶雄进文章来源:http://blog.csdn.net/joexiongjin/article/category/782739
|