void exportGraphicsDiff(DataTable geomDiffRes, int modelIDNew, int modelIDRef, string zippedX3DFiles) { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); Directory.CreateDirectory(tempDirectory); geomDiffRes.Columns.Add("GraphicFile"); foreach (DataRow row in geomDiffRes.Rows) { string elemid = row["Elementid"].ToString(); string x3dFile = elemid + ".x3d"; BIMRLExportSDOToX3D x3dExp = new BIMRLExportSDOToX3D(m_BIMRLCommonRef, Path.Combine(tempDirectory, x3dFile)); // Initialize first if (row["Bounding Box (New)"] != null) { x3dExp.IDsToHighlight.Add(elemid); x3dExp.highlightColor = new ColorSpec(); x3dExp.highlightColor.emissiveColorRed = 255; // Set the New object to RED color x3dExp.highlightColor.emissiveColorGreen = 0; x3dExp.highlightColor.emissiveColorBlue = 0; x3dExp.transparencyOverride = 0.30; x3dExp.exportElemGeomToX3D(modelIDNew, "elementid='" + elemid + "'"); } if (row["Bounding Box (Ref)"] != null) { x3dExp.IDsToHighlight.Add(elemid); x3dExp.highlightColor.emissiveColorRed = 0; // Set the New object to BLUE color x3dExp.highlightColor.emissiveColorGreen = 0; x3dExp.highlightColor.emissiveColorBlue = 255; x3dExp.transparencyOverride = 0.30; x3dExp.exportElemGeomToX3D(modelIDRef, "elementid='" + elemid + "'"); } // Add background element from IFCSLAB to give a sense of spatial relative location x3dExp.transparencyOverride = 0.9; string whereCondElemGeom = "ELEMENTID IN (SELECT ELEMENTID FROM " + DBOperation.formatTabName("BIMRL_ELEMENT", compNewModel.Value) + " WHERE elementtype like 'IFCSLAB%')"; x3dExp.exportElemGeomToX3D(modelIDNew, whereCondElemGeom); x3dExp.endExportToX3D(); row["GraphicFile"] = x3dFile; } if (File.Exists(zippedX3DFiles)) { File.Delete(zippedX3DFiles); } try { using (ZipFile zip = new ZipFile(zippedX3DFiles)) { zip.AddDirectory(tempDirectory); zip.Save(); Directory.Delete(tempDirectory, true); } } catch (Exception e) { throw new Exception("Error during writing the zip file! " + e.Message); } }
private void Button_genX3D_Click(object sender, RoutedEventArgs e) { string whereCond = string.Empty; int fedModelID = 0; FederatedModelInfo selFedModel; FederatedModelInfo selFedModelsItem = DataGrid_FedModels.SelectedItem as FederatedModelInfo; if (selFedModelsItem == null) { return; // do nothing, no selection made } else { selFedModel = selFedModelsItem; fedModelID = selFedModel.FederatedID; } try { BIMRLModelInfo selModelInfo; BIMRLModelInfo?selModelInfosItem = DataGrid_ModelInfos.SelectedItem as BIMRLModelInfo?; if (selModelInfosItem != null) { if (selModelInfosItem.HasValue) { selModelInfo = selModelInfosItem.Value; whereCond += " and ModelID = " + selModelInfo.ModelID + " "; } } if (!string.IsNullOrEmpty(TextBox_Additional_Condition.Text)) { if (!string.IsNullOrEmpty(whereCond)) { whereCond += " AND "; } whereCond += " " + TextBox_Additional_Condition.Text + " "; } BIMRLExportSDOToX3D x3dExp = new BIMRLExportSDOToX3D(BIMRLCommonRef, TextBox_X3D_filename.Text); if (!string.IsNullOrEmpty(TextBox_AlternateUserTable.Text)) { x3dExp.altUserTable = TextBox_AlternateUserTable.Text; } x3dExp.exportToX3D(fedModelID, whereCond, drawElemGeom, drawUserGeom, drawFacesOnly, drawOctree, drawWorldBB); x3dExp.endExportToX3D(); } catch (SystemException excp) { string excStr = "%% Error - " + excp.Message + "\n\t"; BIMRLCommonRef.StackPushError(excStr); if (BIMRLCommonRef.BIMRLErrorStackCount > 0) { showError(null); } } }
public static void Process(OctreeNode node, Polyhedron _polyH, List <Face3D> polyHF) { // 3rd step. Subdivide the cells collected by the step 2 and operate on them with the actual polyhedron to get the detail if (node._depth < Octree.MaxDepth) { int disjointCount = 0; int insideCount = 0; Split(node); List <int> childToRemove = new List <int>(); List <int> childToTraverse = new List <int>(); List <Face3D> faceList; faceList = Face3D.exclFacesOutsideOfBound(polyHF, node.nodeCellCuboid.cuboidPolyhedron.boundingBox, 0x111); if (faceList.Count == 0) { // No face inside this cuboid left, no intersection nor completely enclosing the polyH. node._flag = PolyhedronIntersectEnum.Disjoint; node._children.Clear(); return; } for (int i = 0; i < node._children.Count; i++) { OctreeNode childNode = node._children[i]; //PolyhedronIntersectEnum intS = childNode.Process(polyH); if (Polyhedron.intersect(childNode.nodeCellCuboid.cuboidPolyhedron, faceList)) { childToTraverse.Add(i); childNode._flag = PolyhedronIntersectEnum.Intersect; childNode.nodeCellID.setBorderCell(); #if (DBG_OCTREE) if (childNode._depth >= _dbgDepth) { BIMRLCommon refCommon = new BIMRLCommon(); string dbgFile = "c:\\temp\\octree\\" + childNode.nodeCellID.ToString() + " - intersect polyH.x3d"; BIMRLExportSDOToX3D x3d = new BIMRLExportSDOToX3D(refCommon, dbgFile); x3d.drawCellInX3d(childNode.nodeCellID.ToString()); // draw the cell x3d.exportFacesToX3D(faceList); x3d.endExportToX3D(); } #endif continue; } // If doesn't intersect (passes the check above), either it is fully contained, full contains or disjoint // To optimize the operation, we will use a single sampling point instead of checking the entire polyhedron since a single point can tell if a polyhedron is inside the other one //if (Polyhedron.inside(childNode.nodeCellCuboid.cuboidPolyhedron, polyH)) //// No need to check this since the previous step (no 1) would have removed the fullycontaining cells // Fully contains check only valid if the parent is fully contains, if intersect, it should never be full contains //if (node._flag == PolyhedronIntersectEnum.FullyContains) //{ // if (Polyhedron.insideCuboid(childNode.nodeCellCuboid.cuboidPolyhedron, faceList[0].vertices[0])) // { // // if polyH is entirely inside the cuboid, we will set this for further split (the same as intersection // childToTraverse.Add(i); // We will remove the node if it is disjoint, otherwise it will continue splitting until the condition met // childNode._flag = PolyhedronIntersectEnum.FullyContains; // childNode.nodeCellID.setBorderCell(); // continue; // } //} //if (Polyhedron.inside(polyH, childNode.nodeCellCuboid.cuboidPolyhedron)) if (Polyhedron.inside(_polyH, childNode.nodeCellCuboid.cuboidPolyhedron.Vertices[3])) { childNode._flag = PolyhedronIntersectEnum.Inside; insideCount++; #if (DBG_OCTREE) if (childNode._depth >= _dbgDepth) { BIMRLCommon refCommon = new BIMRLCommon(); string dbgFile = "c:\\temp\\octree\\" + childNode.nodeCellID.ToString() + " - inside polyH.x3d"; BIMRLExportSDOToX3D x3d = new BIMRLExportSDOToX3D(refCommon, dbgFile); x3d.drawCellInX3d(childNode.nodeCellID.ToString()); // draw the cell x3d.exportFacesToX3D(_polyH.Faces); x3d.endExportToX3D(); } #endif continue; } // If the 2 polyH do not intersect, the cuboid does not fully contain the polyH, nor the cuboid is fully inside the polyH, it must be disjoint childNode._flag = PolyhedronIntersectEnum.Disjoint; disjointCount++; #if (DBG_OCTREE) if (childNode._depth >= _dbgDepth) { BIMRLCommon refCommon = new BIMRLCommon(); string dbgFile = "c:\\temp\\octree\\" + childNode.nodeCellID.ToString() + " - disjoint polyH.x3d"; BIMRLExportSDOToX3D x3d = new BIMRLExportSDOToX3D(refCommon, dbgFile); x3d.drawCellInX3d(childNode.nodeCellID.ToString()); // draw the cell x3d.exportFacesToX3D(_polyH.Faces); x3d.endExportToX3D(); } #endif continue; // else: the cuboid is completely inside the polyH, keep } if (disjointCount == 8) { // All children are disjoint. Remove all children and set the node to Disjoint node._children.Clear(); node._flag = PolyhedronIntersectEnum.Disjoint; return; } if (insideCount == 8) { // All children are inside. Remove all children and set the node to Inside node._children.Clear(); node._flag = PolyhedronIntersectEnum.Inside; return; } if (childToTraverse.Count == 1) { OctreeNodeProcess.Process(node._children[childToTraverse[0]], _polyH, faceList); } else if (childToTraverse.Count > 1) { #if (DEBUG_NOPARALLEL) // Non - parallel option for easier debugging foreach (int i in childToTraverse) { OctreeNodeProcess.Process(node._children[i], _polyH, faceList); } #else ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = 8; Parallel.ForEach(childToTraverse, po, i => OctreeNodeProcess.Process(node._children[i], _polyH, faceList)); #endif } // If there is any disjoint, we need to keep this node as it is. This should be done after we processed all the children to be traversed!! if (disjointCount > 0 && disjointCount < 8) { return; } int countGrandChildren = 0; // If there is no disjoint, we need to check whether all children are terminal (i.e. child._children.Count == 0) foreach (OctreeNode child in node._children) { countGrandChildren += child._children.Count; } // All children are terminal and no disjoint (by implication of previous steps). Remove children if (countGrandChildren == 0) { node._children.Clear(); node._flag = PolyhedronIntersectEnum.IntersectOrInside; return; } } else { // at _depth == Octree.MaxDepth there is nothing else to do since the test has been done at the parent level and when entering this stage, the test has determined // that the cell is intersected with the polyH } return; }