我正在开发一个应用程序,可以在 Forge 查看器中重现从 Revit 剪切的剖面框。我使用 Revit api 中的以下代码获得了截面框的最大点和最小点:
BoundingBoxXYZ currentSectionBox = view3D.GetSectionBox();
double[] minPt = new double[] {
currentSectionBox.Transform.Origin.X + currentSectionBox.Min[0],
currentSectionBox.Transform.Origin.Y + currentSectionBox.Min[1],
currentSectionBox.Transform.Origin.Z + currentSectionBox.Min[2]
};
double[] maxPt = new double[] {
currentSectionBox.Transform.Origin.X + currentSectionBox.Max[0],
currentSectionBox.Transform.Origin.Y + currentSectionBox.Max[1],
currentSectionBox.Transform.Origin.Z + currentSectionBox.Max[2]
};
并且可以通过以下代码在revit中重现它:
...
// View3D is the current opened 3d view in revit
View3D.SetSectionBox(new BoundingBoxXYZ() {
Max = new XYZ(maxPt[0], maxPt[1], maxPt[2]),
Min = new XYZ(minPt[0], minPt[1], minPt[2])
});
到目前为止一切顺利,然后我在 forge 查看器中使用了相同的最大和最小点。我希望在 Revit 中看到相同的结果,但事实并非如此。我的代码有什么问题或者我只是误解了一些概念吗?
let offset = this.Viewer3D.model.getData().globalOffset
offset = new THREE.Vector3(offset.x, offset.y, offset.y)
const sectionBoxPosition = new THREE.Box3(minPt.sub(offset), maxPt.sub(offset))
this.Viewer3D.loadExtension('Autodesk.Section').then(function (Section) {
Section.setSectionBox(sectionBoxPosition)
})
您用于应用全局偏移的方式看起来不正确。
我建议您使用
viewer.model.getModelToViewerTransform()
进行如下计算,以获得在查看器中进行转换的正确模型。有时,除了全局偏移之外,还会对模型进行其他转换。
var boxMinFromRvt = new THREE.Vector3(-20.9539269351606, -128.710696355516, -43.8630604978775); //!<<< From Revit API's BoundingBoxXYZ.Min
var boxMaxFromRvt = new THREE.Vector3(73.7218284399634, 102.143481472216, 43.8630604978775); //!<<< From Revit API's BoundingBoxXYZ.Max
var boxTransformFromRvt = new Autodesk.Viewing.Private.LmvMatrix4(true).fromArray([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.49058457162347, -35.3016883690933, 16.5749846091418, 1]); //!<<< From Revit API's BoundingBoxXYZ. Transform
var modelTransform = viewer.model.getModelToViewerTransform();
var minOffseted = boxMinFromRvt.clone().applyMatrix4(boxTransformFromRvt).applyMatrix4(modelTransform);
var maxOffseted = boxMaxFromRvt.clone().applyMatrix4(boxTransformFromRvt).applyMatrix4(modelTransform);
var box = new THREE.Box3(minOffseted, maxOffseted);
viewer.getExtension('Autodesk.Section').setSectionBox(box);
注意。
boxTransformFromRvt
来自 Revit SectionBox 的 BoundingBox.Transform
,如下所示。 (0,0,0,1)
代表变换矩阵的 w 元素,因为 Threejs 的变换是 4x4 (xyzw),但我们从 Revit 得到的是 4x3。
var boxTransformFromRvt = [
Transform.BasicX.X, Transform.BasicX.Y, Transform.BasicX.Z, 0,
Transform.BasicY.X, Transform.BasicY.Y, Transform.BasicY.Z, 0,
Transform.BasicZ.X, Transform.BasicZ.Y, Transform.BasicZ.Z, 0,
Transform.BasicZ.X, Transform.BasicZ.Y, Transform.BasicZ.Z, 0,
Transform.Origin.X, Transform.Origin.Y, Transform.Origin.Z, 1
]
这是我的测试快照: