From b914b6fe53ebda05a8502094816ca6756469be53 Mon Sep 17 00:00:00 2001 From: "mhochsteger@cerbsim.com" Date: Tue, 2 Nov 2021 19:11:10 +0100 Subject: [PATCH 1/3] load/store occ geometry properties (maxh, hpref, color opacity) --- libsrc/occ/occgeom.cpp | 128 ++++++++++++++++++++++++++++++- libsrc/occ/occgeom.hpp | 53 +++++++++++++ libsrc/occ/python_occ_shapes.cpp | 13 ++-- 3 files changed, 183 insertions(+), 11 deletions(-) diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp index ec37e424..c909c67b 100644 --- a/libsrc/occ/occgeom.cpp +++ b/libsrc/occ/occgeom.cpp @@ -30,6 +30,10 @@ #include #endif +#include +#include +#include + #if OCC_VERSION_HEX < 0x070000 // pass #elif OCC_VERSION_HEX < 0x070200 @@ -1571,6 +1575,7 @@ namespace netgen } // for (auto pair : shape_names) // cout << "name = " << pair.second << endl; + step_utils::LoadProperties(model, transProc); } for (auto [s,n] : shape_names) @@ -1750,9 +1755,7 @@ namespace netgen } else if (strcmp (&filename[strlen(filename)-3], "stp") == 0) { - STEPControl_Writer writer; - writer.Transfer (shape, STEPControl_AsIs); - writer.Write (filename); + step_utils::WriteSTEP(*this, filename); } else if (strcmp (&filename[strlen(filename)-3], "stl") == 0) { @@ -2105,6 +2108,125 @@ namespace netgen // return OCCGenerateMesh (*this, mesh, mparam, occparam); // } static RegisterClassForArchive regnggeo; + + namespace step_utils + { + void LoadProperties(const Handle(Interface_InterfaceModel) model, Handle(Transfer_TransientProcess) transProc) + { + Standard_Integer nb = model->NbEntities(); + for (Standard_Integer i = 1; i < nb; i++) + { + Handle(Standard_Transient) entity = model->Value(i); + + auto item = Handle(StepRepr_CompoundRepresentationItem)::DownCast(entity); + + if(item.IsNull()) + continue; + + string name = item->Name()->ToCString(); + if(name != "netgen_geometry_properties") + continue; + + auto shape_item = item->ItemElementValue(1); + Handle(Transfer_Binder) binder; + binder = transProc->Find(shape_item); + TopoDS_Shape shape = TransferBRep::ShapeResult(binder); + auto & prop = OCCGeometry::global_shape_properties[shape.TShape()]; + + auto nprops = item->NbItemElement(); + + for(auto i : Range(2, nprops+1)) + { + auto prop_item = item->ItemElementValue(i); + string prop_name = prop_item->Name()->ToCString(); + + if(prop_name=="maxh") + prop.maxh = Handle(StepRepr_ValueRepresentationItem)::DownCast(prop_item) + ->ValueComponentMember()->Real(); + + if(prop_name=="opacity") + (*prop.col)[3] = Handle(StepRepr_ValueRepresentationItem)::DownCast(prop_item) + ->ValueComponentMember()->Real(); + + if(prop_name=="hpref") + prop.hpref = Handle(StepRepr_ValueRepresentationItem)::DownCast(prop_item) + ->ValueComponentMember()->Real(); + } + } + } + + void WriteProperties(const Handle(Interface_InterfaceModel) model, const Handle(Transfer_FinderProcess) finder, const TopoDS_Shape & shape) + { + static const ShapeProperties default_props; + Handle(StepRepr_RepresentationItem) item = STEPConstruct::FindEntity(finder, shape); + if(!item) + return; + auto prop = OCCGeometry::global_shape_properties[shape.TShape()]; + + if(auto n = prop.name) + item->SetName(MakeName(*n)); + + Array props; + props.Append(item); + + if(auto maxh = prop.maxh; maxh != default_props.maxh) + props.Append( MakeReal(maxh, "maxh") ); + + if(auto col = prop.col) + props.Append( MakeReal((*col)[3], "opacity") ); + + if(auto hpref = prop.hpref; hpref != default_props.hpref) + props.Append( MakeReal(hpref, "hpref") ); + + if(props.Size()==1) + return; + + for(auto & item : props.Range(1, props.Size())) + model->AddEntity(item); + + auto compound = MakeCompound(props, "netgen_geometry_properties"); + model->AddEntity(compound); + } + + void WriteSTEP(const TopoDS_Shape & shape, string filename) + { + Interface_Static::SetCVal("write.step.schema", "AP242IS"); + Interface_Static::SetIVal("write.step.assembly",1); + Handle(XCAFApp_Application) app = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) doc; + + app->NewDocument("STEP-XCAF", doc); + Handle(XCAFDoc_ShapeTool) shapetool = XCAFDoc_DocumentTool::ShapeTool(doc->Main()); + Handle(XCAFDoc_ColorTool) colortool = XCAFDoc_DocumentTool::ColorTool(doc->Main()); + TDF_Label label = shapetool->NewShape(); + shapetool->SetShape(label, shape); + + Handle(XSControl_WorkSession) session = new XSControl_WorkSession; + STEPCAFControl_Writer writer(session); + const Handle(Interface_InterfaceModel) model = session->Model(); + + // Set colors (BEFORE transferring shape into step data structures) + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + { + auto prop = OCCGeometry::global_shape_properties[e.Current().TShape()]; + if(auto col = prop.col) + colortool->SetColor(e.Current(), Quantity_Color((*col)[0], (*col)[1], (*col)[2], Quantity_TypeOfColor::Quantity_TOC_RGB), XCAFDoc_ColorGen); + } + + // Transfer shape into step data structures -> now we can manipulate/add step representation items + writer.Transfer(doc, STEPControl_AsIs); + + // Write all other properties + auto finder = session->TransferWriter()->FinderProcess(); + + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + WriteProperties(model, finder, e.Current()); + + writer.Write(filename.c_str()); + } + } // namespace step_utils } diff --git a/libsrc/occ/occgeom.hpp b/libsrc/occ/occgeom.hpp index 959691c8..5eb1f1e6 100644 --- a/libsrc/occ/occgeom.hpp +++ b/libsrc/occ/occgeom.hpp @@ -85,6 +85,11 @@ #include "IGESControl_Writer.hxx" #include "STEPControl_Writer.hxx" +#include +#include +#include +#include + #include "StlAPI_Writer.hxx" #include "STEPControl_StepModelType.hxx" @@ -229,6 +234,7 @@ namespace netgen } }; + class OCCIdentification { public: @@ -505,6 +511,53 @@ namespace netgen DLL_HEADER extern void OCCOptimizeSurface (OCCGeometry & geom, Mesh & mesh, const MeshingParameters & mparam); DLL_HEADER extern void OCCFindEdges (const OCCGeometry & geom, Mesh & mesh, const MeshingParameters & mparam); + + + namespace step_utils + { + inline Handle(TCollection_HAsciiString) MakeName (string s) + { + return new TCollection_HAsciiString(s.c_str()); + }; + + inline Handle(StepRepr_RepresentationItem) MakeInt (int n, string name = "") + { + Handle(StepRepr_IntegerRepresentationItem) int_obj = new StepRepr_IntegerRepresentationItem; + int_obj->Init(MakeName(name), n); + return int_obj; + } + + inline Handle(StepRepr_RepresentationItem) MakeReal (double val, string name = "") + { + Handle(StepBasic_MeasureValueMember) value_member = new StepBasic_MeasureValueMember; + value_member->SetReal(val); + Handle(StepRepr_ValueRepresentationItem) value_repr = new StepRepr_ValueRepresentationItem; + value_repr->Init(MakeName(name), value_member); + return value_repr; + } + + inline Handle(StepRepr_RepresentationItem) MakeCompound( FlatArray items, string name = "" ) + { + Handle(StepRepr_HArray1OfRepresentationItem) array_repr = new StepRepr_HArray1OfRepresentationItem(1,items.Size()); + + for(auto i : Range(items)) + array_repr->SetValue(i+1, items[i]); + + Handle(StepRepr_CompoundRepresentationItem) comp = new StepRepr_CompoundRepresentationItem; + comp->Init( MakeName(name), array_repr ); + return comp; + } + + void LoadProperties(const Handle(Interface_InterfaceModel) model, Handle(Transfer_TransientProcess) transProc); + void WriteProperties(const Handle(Interface_InterfaceModel) model, const Handle(Transfer_FinderProcess) finder, const TopoDS_Shape & shape); + + void WriteSTEP(const TopoDS_Shape & shape, string filename); + + inline void WriteSTEP(const OCCGeometry & geo, string filename) + { + WriteSTEP(geo.GetShape(), filename); + } + } // namespace step_utils } #endif diff --git a/libsrc/occ/python_occ_shapes.cpp b/libsrc/occ/python_occ_shapes.cpp index 60995495..8553619a 100644 --- a/libsrc/occ/python_occ_shapes.cpp +++ b/libsrc/occ/python_occ_shapes.cpp @@ -27,6 +27,8 @@ #include // #include #include +#include +#include #include #include #include @@ -836,14 +838,9 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) }, py::arg("p"), py::arg("s"), "copy shape, and scale copy by factor 's'") - .def("WriteStep", [](TopoDS_Shape shape, string filename) - { - STEPControl_Writer writer; - writer.Transfer(shape, STEPControl_ManifoldSolidBrep); - - // Translates TopoDS_Shape into manifold_solid_brep entity - writer.Write(filename.c_str()); - }, py::arg("filename"), "export shape in STEP - format") + .def("WriteStep", [](const TopoDS_Shape & shape, string & filename) + { step_utils::WriteSTEP(shape, filename); } + , py::arg("filename"), "export shape in STEP - format") .def("bc", [](const TopoDS_Shape & shape, const string & name) { From 9245c3c32bc8824d60e36b3037812b5dff9c7f51 Mon Sep 17 00:00:00 2001 From: "mhochsteger@cerbsim.com" Date: Wed, 3 Nov 2021 17:20:26 +0100 Subject: [PATCH 2/3] proper handling of occ names and colors --- libsrc/occ/occgenmesh.cpp | 28 +--- libsrc/occ/occgeom.cpp | 277 +++++++++++++------------------------- libsrc/occ/occgeom.hpp | 32 +++-- libsrc/occ/vsocc.cpp | 26 +--- 4 files changed, 125 insertions(+), 238 deletions(-) diff --git a/libsrc/occ/occgenmesh.cpp b/libsrc/occ/occgenmesh.cpp index bb801a0c..e24eccb8 100644 --- a/libsrc/occ/occgenmesh.cpp +++ b/libsrc/occ/occgenmesh.cpp @@ -408,29 +408,11 @@ namespace netgen mesh.AddFaceDescriptor (FaceDescriptor(facenr, solidnr0, solidnr1, 0)); - // Philippose - 06/07/2009 - // Add the face colour to the mesh data - Quantity_Color face_colour; + Vec<4> col = OCCGeometry::global_shape_properties[face.TShape()].col.value_or(Vec<4>(0,1,0,1)); + mesh.GetFaceDescriptor(facenr).SetSurfColour(col); - if(!(geom.face_colours.IsNull()) - && (geom.face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour))) - { - mesh.GetFaceDescriptor(facenr).SetSurfColour({face_colour.Red(),face_colour.Green(),face_colour.Blue()}); - } - else - { - auto it = OCCGeometry::global_shape_properties.find(face.TShape()); - if (it != OCCGeometry::global_shape_properties.end() && it->second.col) - { - Vec<4> col = it->second.col.value_or(Vec<4>(0,1,0,1)); - mesh.GetFaceDescriptor(facenr).SetSurfColour(col); - } - else - mesh.GetFaceDescriptor(facenr).SetSurfColour({0.0,1.0,0.0}); - } - - if(geom.fnames.Size()>=facenr) - mesh.GetFaceDescriptor(facenr).SetBCName(&geom.fnames[facenr-1]); + if(auto opt_name = geom.fprops[facenr-1]->name) + mesh.GetFaceDescriptor(facenr).SetBCName(&*opt_name); mesh.GetFaceDescriptor(facenr).SetBCProperty(facenr); // ACHTUNG! STIMMT NICHT ALLGEMEIN (RG) @@ -602,7 +584,7 @@ namespace netgen alledgeparams[geomedgenr-1] = params; } - auto name = geom.enames.Size() ? geom.enames[geom.emap.FindIndex(edge)-1] : ""; + auto name = geom.eprops[geom.emap.FindIndex(edge)-1]->name.value_or(""); mesh.SetCD2Name(geomedgenr, name); (*testout) << "NP = " << mesh.GetNP() << endl; diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp index c909c67b..73e28684 100644 --- a/libsrc/occ/occgeom.cpp +++ b/libsrc/occ/occgeom.cpp @@ -33,6 +33,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #if OCC_VERSION_HEX < 0x070000 // pass @@ -45,47 +51,17 @@ namespace netgen { + void LoadOCCInto(OCCGeometry* occgeo, const char* filename); - // std::map OCCGeometry::global_shape_names; - // std::map> OCCGeometry::global_shape_cols; std::map OCCGeometry::global_shape_properties; std::map> OCCGeometry::identifications; OCCGeometry::OCCGeometry(const TopoDS_Shape& _shape, int aoccdim) { - shape = _shape; + auto filename = ".tmpfile_out.step"; + step_utils::WriteSTEP(_shape, filename); + LoadOCCInto(this, filename); occdim = aoccdim; - changed = true; - BuildFMap(); - CalcBoundingBox(); - - snames.SetSize(somap.Size()); - for(auto i : Range(snames)) - snames[i] = "domain_" + ToString(i+1); - for (TopExp_Explorer e(shape, TopAbs_SOLID); e.More(); e.Next()) - { - TopoDS_Solid solid = TopoDS::Solid(e.Current()); - if (auto name = global_shape_properties[solid.TShape()].name) - snames[somap.FindIndex(solid)-1] = *name; - } - - fnames.SetSize(fmap.Size()); - for(auto i : Range(fnames)) - fnames[i] = "bc_" + ToString(i+1); - for(TopExp_Explorer e(shape, TopAbs_FACE); e.More(); e.Next()) - { - TopoDS_Face face = TopoDS::Face(e.Current()); - if (auto name = global_shape_properties[face.TShape()].name) - fnames[fmap.FindIndex(face)-1] = *name; - } - enames.SetSize(emap.Size()); - enames = ""; - for (TopExp_Explorer e(shape, TopAbs_EDGE); e.More(); e.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(e.Current()); - if (auto name = global_shape_properties[edge.TShape()].name) - enames[emap.FindIndex(edge)-1] = *name; - } } string STEP_GetEntityName(const TopoDS_Shape & theShape, STEPCAFControl_Reader * aReader) @@ -142,8 +118,8 @@ namespace netgen void OCCGeometry :: FinalizeMesh(Mesh& mesh) const { for (int i = 0; i < mesh.GetNDomains(); i++) - if (snames.Size()) - mesh.SetMaterial (i+1, snames[i]); + if (auto name = sprops[i]->name) + mesh.SetMaterial (i+1, *name); } void OCCGeometry :: PrintNrShapes () @@ -368,22 +344,10 @@ namespace netgen Handle(ShapeBuild_ReShape) rebuild = new ShapeBuild_ReShape; rebuild->Apply(shape); - for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) { - // Variable to hold the colour (if there exists one) of - // the current face being processed - Quantity_Color face_colour; - TopoDS_Face face = TopoDS::Face (exp0.Current()); - - if(face_colours.IsNull() - || (!(face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour)))) - { - // Set the default face colour to green (Netgen Standard) - // if no colour has been defined for the face - face_colour = Quantity_Color(0.0,1.0,0.0,Quantity_TOC_RGB); - } + auto props = global_shape_properties[face.TShape()]; sff = new ShapeFix_Face (face); sff->FixAddNaturalBoundMode() = Standard_True; @@ -412,11 +376,9 @@ namespace netgen rebuild->Replace(face, newface); } - // Set the original colour of the face to the newly created + // Set the original properties of the face to the newly created // face (after the healing process) - face = TopoDS::Face (exp0.Current()); - if(face_colours) - face_colours->SetColor(face,face_colour,XCAFDoc_ColorSurf); + global_shape_properties[face.TShape()]; } shape = rebuild->Apply(shape); } @@ -1058,6 +1020,28 @@ namespace netgen vsingular.SetSize (vmap.Extent()); fsingular = esingular = vsingular = false; + + + sprops.SetSize(somap.Extent()); + for (TopExp_Explorer e(shape, TopAbs_SOLID); e.More(); e.Next()) + { + auto s = e.Current(); + sprops[somap.FindIndex(s)-1] = &global_shape_properties[s.TShape()]; + } + + fprops.SetSize(fmap.Extent()); + for (TopExp_Explorer e(shape, TopAbs_FACE); e.More(); e.Next()) + { + auto s = e.Current(); + fprops[fmap.FindIndex(s)-1] = &global_shape_properties[s.TShape()]; + } + + eprops.SetSize(emap.Extent()); + for (TopExp_Explorer e(shape, TopAbs_EDGE); e.More(); e.Next()) + { + auto s = e.Current(); + eprops[emap.FindIndex(s)-1] = &global_shape_properties[s.TShape()]; + } } @@ -1495,128 +1479,22 @@ namespace netgen timer_transfer.Stop(); // Read in the shape(s) and the colours present in the STEP File - Handle(XCAFDoc_ShapeTool) step_shape_contents = XCAFDoc_DocumentTool::ShapeTool(step_doc->Main()); - Handle(XCAFDoc_ColorTool) step_colour_contents = XCAFDoc_DocumentTool::ColorTool(step_doc->Main()); + auto step_shape_contents = XCAFDoc_DocumentTool::ShapeTool(step_doc->Main()); TDF_LabelSequence step_shapes; step_shape_contents->GetShapes(step_shapes); - // List out the available colours in the STEP File as Colour Names - TDF_LabelSequence all_colours; - step_colour_contents->GetColors(all_colours); - PrintMessage(1,"Number of colours in STEP File: ",all_colours.Length()); - for(int i = 1; i <= all_colours.Length(); i++) - { - Quantity_Color col; - stringstream col_rgb; - step_colour_contents->GetColor(all_colours.Value(i),col); - col_rgb << " : (" << col.Red() << "," << col.Green() << "," << col.Blue() << ")"; - PrintMessage(1, "Colour [", i, "] = ",col.StringName(col.Name()),col_rgb.str()); - } - - // For the STEP File Reader in OCC, the 1st Shape contains the entire // compound geometry as one shape - occgeo->shape = step_shape_contents->GetShape(step_shapes.Value(1)); - occgeo->face_colours = step_colour_contents; + auto main_shape = step_shape_contents->GetShape(step_shapes.Value(1)); + + step_utils::LoadProperties(main_shape, reader, step_doc); + + occgeo->shape = main_shape; occgeo->changed = 1; occgeo->BuildFMap(); - occgeo->CalcBoundingBox(); PrintContents (occgeo); - string name; - TopExp_Explorer exp0,exp1; - - - - std::map shape_names; - { - static Timer t("file shape_names"); RegionTimer r(t); - // code inspired from - // https://www.opencascade.com/content/reading-step-entity-id-slow - const Handle(XSControl_WorkSession) workSession = reader.Reader().WS(); - const Handle(Interface_InterfaceModel) model = workSession->Model(); - const Handle(XSControl_TransferReader) transferReader = workSession->TransferReader(); - Handle(Transfer_TransientProcess) transProc = transferReader->TransientProcess(); - - Standard_Integer nb = model->NbEntities(); - for (Standard_Integer i = 1; i < nb; i++) - { - Handle(Standard_Transient) entity = model->Value(i); - - // if (!entity->DynamicType()->SubType("StepShape_OpenShell")) continue; - - Handle(StepRepr_RepresentationItem) SRRI = - Handle(StepRepr_RepresentationItem)::DownCast(entity); - - if (SRRI.IsNull()) { - // cout << "no StepRepr_RepresentationItem found in " << entity->DynamicType()->Name(); - continue; - } - Handle(TCollection_HAsciiString) hName = SRRI->Name(); - string shapeName = hName->ToCString(); - - // cout << "STEP " << i << " " << entity->DynamicType()->Name() << ", shapename = " << shapeName; - Handle(Transfer_Binder) binder; - if (!transProc->IsBound(SRRI)) { - // cout << "found unbound entity " << shapeName; - continue; - } - binder = transProc->Find(SRRI); - TopoDS_Shape shape = TransferBRep::ShapeResult(binder); - // if (!shape.IsNull()) - shape_names[shape.TShape()] = shapeName; - /* - if (!shape.IsNull()) - cout << " shapetype = " << shape.ShapeType() << endl; - else - cout << "is-Null" << endl; - */ - } - // for (auto pair : shape_names) - // cout << "name = " << pair.second << endl; - step_utils::LoadProperties(model, transProc); - } - - for (auto [s,n] : shape_names) - OCCGeometry::global_shape_properties[s].name = n; - - - timer_getnames.Start(); - occgeo->snames.SetSize(occgeo->somap.Size()); - for (exp0.Init(occgeo->shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); - // name = STEP_GetEntityName(solid,&reader); - // cout << "solidname = " << name << ", mapname = " << shape_names[solid.TShape()] << endl; - name = shape_names[solid.TShape()]; - if (name == "") - name = string("domain_") + ToString(occgeo->snames.Size()); - occgeo->snames[occgeo->somap.FindIndex(solid)-1] = name; - } - - occgeo->fnames.SetSize(occgeo->fmap.Size()); - occgeo->enames.SetSize(occgeo->emap.Size()); - for (exp0.Init(occgeo->shape, TopAbs_FACE); exp0.More(); exp0.Next()) - { - TopoDS_Face face = TopoDS::Face(exp0.Current()); - // name = STEP_GetEntityName(face,&reader); - // cout << "getname = " << name << ", mapname = " << shape_names[face.TShape()] << endl; - name = shape_names[face.TShape()]; - auto index = occgeo->fmap.FindIndex(face); - if (name == "") - name = string("bc_") + ToString(index); - occgeo->fnames[index-1] = name; - for (exp1.Init(face, TopAbs_EDGE); exp1.More(); exp1.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - // name = STEP_GetEntityName(edge,&reader); - // cout << "getname = " << name << ", mapname = " << shape_names[edge.TShape()] << endl; - name = shape_names[edge.TShape()]; - occgeo->enames[occgeo->emap.FindIndex(edge)-1] = name; - } - } - timer_getnames.Stop(); } // Philippose - 23/02/2009 @@ -1681,7 +1559,6 @@ namespace netgen // For the IGES Reader, all the shapes can be exported as one compound shape // using the "OneShape" member occgeo->shape = reader.OneShape(); - occgeo->face_colours = iges_colour_contents; occgeo->changed = 1; occgeo->BuildFMap(); @@ -1725,12 +1602,6 @@ namespace netgen return NULL; } - // Philippose - 23/02/2009 - // Fixed a bug in the OpenCascade XDE Colour handling when - // opening BREP Files, since BREP Files have no colour data. - // Hence, the face_colours Handle needs to be created as a NULL handle. - occgeo->face_colours = Handle(XCAFDoc_ColorTool)(); - occgeo->face_colours.Nullify(); occgeo->changed = 1; occgeo->BuildFMap(); @@ -2111,9 +1982,59 @@ namespace netgen namespace step_utils { - void LoadProperties(const Handle(Interface_InterfaceModel) model, Handle(Transfer_TransientProcess) transProc) + void LoadProperties(const TopoDS_Shape & shape, + const STEPCAFControl_Reader & reader, + const Handle(TDocStd_Document) step_doc) { + static Timer t("step_utils::LoadProperties"); RegionTimer rt(t); + + auto workSession = reader.Reader().WS(); + auto model = workSession->Model(); + auto transferReader = workSession->TransferReader(); + auto transProc = transferReader->TransientProcess(); + auto shapeTool = XCAFDoc_DocumentTool::ShapeTool(step_doc->Main()); + + // load colors + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + { + TDF_Label label; + shapeTool->Search(e.Current(), label); + + if(label.IsNull()) + continue; + + XCAFPrs_IndexedDataMapOfShapeStyle set; + TopLoc_Location loc; + XCAFPrs::CollectStyleSettings(label, loc, set); + XCAFPrs_Style aStyle; + set.FindFromKey(e.Current(), aStyle); + + auto & prop = OCCGeometry::global_shape_properties[e.Current().TShape()]; + if(aStyle.IsSetColorSurf()) + prop.col = step_utils::ReadColor(aStyle.GetColorSurfRGBA()); + } + + // load names Standard_Integer nb = model->NbEntities(); + for (Standard_Integer i = 1; i < nb; i++) + { + Handle(Standard_Transient) entity = model->Value(i); + auto item = Handle(StepRepr_RepresentationItem)::DownCast(entity); + + if(item.IsNull()) + continue; + + TopoDS_Shape shape = TransferBRep::ShapeResult(transProc->Find(item)); + string name = item->Name()->ToCString(); + if (!transProc->IsBound(item)) + continue; + + OCCGeometry::global_shape_properties[shape.TShape()].name = name; + } + + + // load custom data (maxh etc.) for (Standard_Integer i = 1; i < nb; i++) { Handle(Standard_Transient) entity = model->Value(i); @@ -2144,10 +2065,6 @@ namespace netgen prop.maxh = Handle(StepRepr_ValueRepresentationItem)::DownCast(prop_item) ->ValueComponentMember()->Real(); - if(prop_name=="opacity") - (*prop.col)[3] = Handle(StepRepr_ValueRepresentationItem)::DownCast(prop_item) - ->ValueComponentMember()->Real(); - if(prop_name=="hpref") prop.hpref = Handle(StepRepr_ValueRepresentationItem)::DownCast(prop_item) ->ValueComponentMember()->Real(); @@ -2172,9 +2089,6 @@ namespace netgen if(auto maxh = prop.maxh; maxh != default_props.maxh) props.Append( MakeReal(maxh, "maxh") ); - if(auto col = prop.col) - props.Append( MakeReal((*col)[3], "opacity") ); - if(auto hpref = prop.hpref; hpref != default_props.hpref) props.Append( MakeReal(hpref, "hpref") ); @@ -2211,7 +2125,7 @@ namespace netgen { auto prop = OCCGeometry::global_shape_properties[e.Current().TShape()]; if(auto col = prop.col) - colortool->SetColor(e.Current(), Quantity_Color((*col)[0], (*col)[1], (*col)[2], Quantity_TypeOfColor::Quantity_TOC_RGB), XCAFDoc_ColorGen); + colortool->SetColor(e.Current(), step_utils::MakeColor(*col), XCAFDoc_ColorGen); } // Transfer shape into step data structures -> now we can manipulate/add step representation items @@ -2226,6 +2140,7 @@ namespace netgen writer.Write(filename.c_str()); } + } // namespace step_utils } diff --git a/libsrc/occ/occgeom.hpp b/libsrc/occ/occgeom.hpp index 5eb1f1e6..a7fc3563 100644 --- a/libsrc/occ/occgeom.hpp +++ b/libsrc/occ/occgeom.hpp @@ -251,20 +251,13 @@ namespace netgen public: static std::map global_shape_properties; static std::map> identifications; - // static std::map global_shape_names; - // static std::map> global_shape_cols; - + TopoDS_Shape shape; TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap; NgArray fsingular, esingular, vsingular; Box<3> boundingbox; - NgArray fnames, enames, snames; - // Philippose - 29/01/2009 - // OpenCascade XDE Support - // XCAF Handle to make the face colours available to the rest of - // the system - Handle(XCAFDoc_ColorTool) face_colours; - + Array fprops, eprops, sprops; // pointers to the gobal property map + mutable int changed; mutable NgArray facemeshstatus; @@ -548,7 +541,21 @@ namespace netgen return comp; } - void LoadProperties(const Handle(Interface_InterfaceModel) model, Handle(Transfer_TransientProcess) transProc); + inline Quantity_ColorRGBA MakeColor(const Vec<4> & c) + { + return Quantity_ColorRGBA (c[0], c[1], c[2], c[3]); + } + + inline Vec<4> ReadColor (const Quantity_ColorRGBA & c) + { + auto rgb = c.GetRGB(); + return {rgb.Red(), rgb.Green(), rgb.Blue(), c.Alpha()}; + } + + + void LoadProperties(const TopoDS_Shape & shape, + const STEPCAFControl_Reader & reader, + const Handle(TDocStd_Document) step_doc); void WriteProperties(const Handle(Interface_InterfaceModel) model, const Handle(Transfer_FinderProcess) finder, const TopoDS_Shape & shape); void WriteSTEP(const TopoDS_Shape & shape, string filename); @@ -557,6 +564,9 @@ namespace netgen { WriteSTEP(geo.GetShape(), filename); } + + // deep copy, also ensures consistent shape ordering (face numbers etc.) + TopoDS_Shape WriteAndRead(const TopoDS_Shape shape); } // namespace step_utils } diff --git a/libsrc/occ/vsocc.cpp b/libsrc/occ/vsocc.cpp index fab16225..3f11f47d 100644 --- a/libsrc/occ/vsocc.cpp +++ b/libsrc/occ/vsocc.cpp @@ -549,29 +549,9 @@ namespace netgen if (!occgeometry->fvispar[i-1].IsHighlighted()) { - // Philippose - 30/01/2009 - // OpenCascade XDE Support - Quantity_Color face_colour; - // Philippose - 23/02/2009 - // Check to see if colours have been extracted first!! - // Forum bug-fox (Jean-Yves - 23/02/2009) - if(!(occgeometry->face_colours.IsNull()) - && (occgeometry->face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour))) - { - mat_col[0] = face_colour.Red(); - mat_col[1] = face_colour.Green(); - mat_col[2] = face_colour.Blue(); - } - else - { - mat_col[0] = 0.0; - mat_col[1] = 1.0; - mat_col[2] = 0.0; - } - - if(auto c = OCCGeometry::global_shape_properties[face.TShape()].col) - for(auto j : Range(4)) - mat_col[j] = (*c)[j]; + auto c = OCCGeometry::global_shape_properties[face.TShape()].col.value_or(Vec<4>(0,1,0,1) ); + for(auto j : Range(4)) + mat_col[j] = c[j]; } else { From dbe9431fa9de7af7cbf78886c9c7d1a72653d73e Mon Sep 17 00:00:00 2001 From: "mhochsteger@cerbsim.com" Date: Wed, 3 Nov 2021 17:42:52 +0100 Subject: [PATCH 3/3] remove temp file --- libsrc/occ/occgeom.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp index 73e28684..537da6ef 100644 --- a/libsrc/occ/occgeom.cpp +++ b/libsrc/occ/occgeom.cpp @@ -62,6 +62,7 @@ namespace netgen step_utils::WriteSTEP(_shape, filename); LoadOCCInto(this, filename); occdim = aoccdim; + std::remove(filename); } string STEP_GetEntityName(const TopoDS_Shape & theShape, STEPCAFControl_Reader * aReader)