diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp index 7214fc9a0fbee7a6eb23b11046d296e4da3ba34e..0a1593de207dd99c3739997cdc067ecdf0d890de 100644 --- a/Geo/GModelIO_OCC.cpp +++ b/Geo/GModelIO_OCC.cpp @@ -31,6 +31,118 @@ #include <Geom_Circle.hxx> #include <Geom_TrimmedCurve.hxx> +OCC_Internals::OCC_Internals() +{ + for(int i = 0; i < 4; i++) + _maxTagConstraints[i] = 0; +} + +void OCC_Internals::bind(TopoDS_Vertex vertex, int tag) +{ + _vertexTag.Bind(vertex, tag); + _tagVertex.Bind(tag, vertex); +} + +void OCC_Internals::bind(TopoDS_Edge edge, int tag) +{ + _edgeTag.Bind(edge, tag); + _tagEdge.Bind(tag, edge); +} + +void OCC_Internals::bind(TopoDS_Wire wire, int tag) +{ + _wireTag.Bind(wire, tag); + _tagWire.Bind(tag, wire); +} + +void OCC_Internals::bind(TopoDS_Face face, int tag) +{ + _faceTag.Bind(face, tag); + _tagFace.Bind(tag, face); +} + +void OCC_Internals::bind(TopoDS_Shell shell, int tag) +{ + _shellTag.Bind(shell, tag); + _tagShell.Bind(tag, shell); +} + +void OCC_Internals::bind(TopoDS_Solid solid, int tag) +{ + _solidTag.Bind(solid, tag); + _tagSolid.Bind(tag, solid); +} + +void OCC_Internals::unbind(TopoDS_Vertex vertex, int tag) +{ + _vertexTag.UnBind(vertex); + _tagVertex.UnBind(tag); +} + +void OCC_Internals::unbind(TopoDS_Edge edge, int tag) +{ + _edgeTag.UnBind(edge); + _tagEdge.UnBind(tag); +} + +void OCC_Internals::unbind(TopoDS_Wire wire, int tag) +{ + _wireTag.UnBind(wire); + _tagWire.UnBind(tag); +} + +void OCC_Internals::unbind(TopoDS_Face face, int tag) +{ + _faceTag.UnBind(face); + _tagFace.UnBind(tag); +} + +void OCC_Internals::unbind(TopoDS_Shell shell, int tag) +{ + _shellTag.UnBind(shell); + _tagShell.UnBind(tag); +} + +void OCC_Internals::unbind(TopoDS_Solid solid, int tag) +{ + _solidTag.UnBind(solid); + _tagSolid.UnBind(tag); +} + +void OCC_Internals::bindHighest(TopoDS_Shape shape, std::vector<int> tags[4]) +{ + TopExp_Explorer exp0; + for(exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()){ + int t = getMaxTag(3) + 1; + bind(TopoDS::Solid(exp0.Current()), t); + tags[3].push_back(t); + } + if(tags[3].size()) return; + for(exp0.Init(shape, TopAbs_FACE); exp0.More(); exp0.Next()){ + int t = getMaxTag(2) + 1; + bind(TopoDS::Face(exp0.Current()), t); + tags[2].push_back(t); + } + if(tags[2].size()) return; + for(exp0.Init(shape, TopAbs_EDGE); exp0.More(); exp0.Next()){ + int t = getMaxTag(1) + 1; + bind(TopoDS::Edge(exp0.Current()), t); + tags[1].push_back(t); + } + if(tags[1].size()) return; + for(exp0.Init(shape, TopAbs_VERTEX); exp0.More(); exp0.Next()){ + int t = getMaxTag(0) + 1; + bind(TopoDS::Edge(exp0.Current()), t); + tags[0].push_back(t); + } +} + +void OCC_Internals::setTagConstraints(int maxTags[4]) +{ + for(int i = 0; i < 4; i++) + _maxTagConstraints[i] = maxTags[i]; +} + int OCC_Internals::getMaxTag(int dim) const { if(dim < 0 || dim > 3) return 0; @@ -567,7 +679,7 @@ void OCC_Internals::getBoundary(std::vector<int> inTags[4], } if(combined){ - // TODO + Msg::Error("OCC TODO CombinedBoundary"); } if(inTags[2].size() || inTags[1].size()){ @@ -587,422 +699,181 @@ void OCC_Internals::translate(std::std::vector<double> dx, int addToTheModel) } */ -void OCC_Internals::_healShape(TopoDS_Shape &myshape, double tolerance, - bool fixdegenerated, bool fixsmalledges, - bool fixspotstripfaces, bool sewfaces, - bool makesolids, double scaling) +void OCC_Internals::importShapes(const std::string &fileName, + std::vector<int> outTags[4]) { - if(scaling != 1.0){ - Msg::Info("Scaling geometry by factor %g", scaling); - gp_Trsf t; - t.SetScaleFactor(scaling); - BRepBuilderAPI_Transform trsf(myshape, t); - myshape = trsf.Shape(); + std::vector<std::string> split = SplitFileName(fileName); + TopoDS_Shape result; + try{ + if(split[2] == ".brep" || split[2] == ".BREP"){ + BRep_Builder aBuilder; + BRepTools::Read(result, fileName.c_str(), aBuilder); + } + else if(split[2] == ".step" || split[2] == ".stp" || + split[2] == ".STEP" || split[2] == ".STP"){ + STEPControl_Reader reader; + if(reader.ReadFile(fileName.c_str()) != IFSelect_RetDone){ + Msg::Error("Could not read file '%s'", fileName.c_str()); + return; + } + reader.TransferRoots(); + result = reader.OneShape(); + } + else{ + Msg::Error("Unknown file type '%s'", fileName.c_str()); + return; + } + // FIXME: apply healing routine on result? + } + catch(Standard_Failure &err){ + Msg::Error("OpenCASCADE exception %s", err.GetMessageString()); + return; } - if(!fixdegenerated && !fixsmalledges && !fixspotstripfaces && - !sewfaces && !makesolids) return; + bindHighest(result, outTags); +} - Msg::Info("Starting shape healing (tolerance: %g)", tolerance); +void OCC_Internals::importShapes(const TopoDS_Shape *shape, std::vector<int> outTags[4]) +{ + bindHighest(*shape, outTags); +} - buildLists(); - TopExp_Explorer exp0, exp1; - int nrc = 0, nrcs = 0; - int nrso = _somap.Extent(), nrsh = _shmap.Extent(), nrf = _fmap.Extent(); - int nrw = _wmap.Extent(), nre = _emap.Extent(), nrv = _vmap.Extent(); - for(exp0.Init(myshape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++; - for(exp0.Init(myshape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++; +void OCC_Internals::exportShapes(const std::string &fileName) +{ + // iterate over all shapes with tags, and import them into the (sub)shape _maps + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp0(_tagVertex); + for(; exp0.More(); exp0.Next()) _addShapeToMaps(exp0.Value()); + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp1(_tagEdge); + for(; exp1.More(); exp1.Next()) _addShapeToMaps(exp1.Value()); + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp2(_tagFace); + for(; exp2.More(); exp2.Next()) _addShapeToMaps(exp2.Value()); + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp3(_tagSolid); + for(; exp3.More(); exp3.Next()) _addShapeToMaps(exp3.Value()); - double surfacecont = 0; - for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ - TopoDS_Face face = TopoDS::Face(exp0.Current()); - GProp_GProps system; - BRepGProp::SurfaceProperties(face, system); - surfacecont += system.Mass(); - } + // build a single compound shape + BRep_Builder b; + TopoDS_Compound c; + b.MakeCompound(c); + for(int i = 1; i <= _vmap.Extent(); i++) b.Add(c, _vmap(i)); + for(int i = 1; i <= _emap.Extent(); i++) b.Add(c, _emap(i)); + for(int i = 1; i <= _wmap.Extent(); i++) b.Add(c, _wmap(i)); + for(int i = 1; i <= _fmap.Extent(); i++) b.Add(c, _fmap(i)); + for(int i = 1; i <= _shmap.Extent(); i++) b.Add(c, _shmap(i)); + for(int i = 1; i <= _somap.Extent(); i++) b.Add(c, _somap(i)); - if(fixdegenerated){ - Msg::Info("- fix degenerated edges and faces"); + std::vector<std::string> split = SplitFileName(fileName); - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); - for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if(BRep_Tool::Degenerated(edge)) - rebuild->Remove(edge, false); + try { + if(split[2] == ".brep" || split[2] == ".BREP"){ + BRepTools::Write(c, fileName.c_str()); + } + else if(split[2] == ".step" || split[2] == ".stp" || + split[2] == ".STEP" || split[2] == ".STP"){ + STEPControl_Writer writer; + if(writer.Transfer(c, STEPControl_ManifoldSolidBrep) == IFSelect_RetDone){ + if(writer.Write(fileName.c_str()) != IFSelect_RetDone){ + Msg::Error("Could not create file '%s'", fileName.c_str()); + } + } + else{ + Msg::Error("Could not create STEP data"); } - myshape = rebuild->Apply(myshape); } - buildLists(); + } + catch(Standard_Failure &err){ + Msg::Error("OCC exception %s", err.GetMessageString()); + } +} - { - Handle(ShapeFix_Face) sff; - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); +void OCC_Internals::synchronize(GModel *model) +{ + int vTagMax = std::max(model->getMaxElementaryNumber(0), getMaxTag(0)); + int eTagMax = std::max(model->getMaxElementaryNumber(1), getMaxTag(1)); + int fTagMax = std::max(model->getMaxElementaryNumber(2), getMaxTag(2)); + int rTagMax = std::max(model->getMaxElementaryNumber(3), getMaxTag(3)); - for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ - TopoDS_Face face = TopoDS::Face(exp0.Current()); + _somap.Clear(); + _shmap.Clear(); + _fmap.Clear(); + _wmap.Clear(); + _emap.Clear(); + _vmap.Clear(); - sff = new ShapeFix_Face(face); - sff->FixAddNaturalBoundMode() = Standard_True; - sff->FixSmallAreaWireMode() = Standard_True; - sff->Perform(); + // iterate over all shapes with tags, and import them into the (sub)shape _maps + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp0(_tagVertex); + for(; exp0.More(); exp0.Next()) _addShapeToMaps(exp0.Value()); + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp1(_tagEdge); + for(; exp1.More(); exp1.Next()) _addShapeToMaps(exp1.Value()); + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp2(_tagFace); + for(; exp2.More(); exp2.Next()) _addShapeToMaps(exp2.Value()); + TopTools_DataMapIteratorOfDataMapOfIntegerShape exp3(_tagSolid); + for(; exp3.More(); exp3.Next()) _addShapeToMaps(exp3.Value()); - if(sff->Status(ShapeExtend_DONE1) || - sff->Status(ShapeExtend_DONE2) || - sff->Status(ShapeExtend_DONE3) || - sff->Status(ShapeExtend_DONE4) || - sff->Status(ShapeExtend_DONE5)) - { - Msg::Info(" repaired face %d", _fmap.FindIndex(face)); - if(sff->Status(ShapeExtend_DONE1)) - Msg::Info(" (some wires are fixed)"); - else if(sff->Status(ShapeExtend_DONE2)) - Msg::Info(" (orientation of wires fixed)"); - else if(sff->Status(ShapeExtend_DONE3)) - Msg::Info(" (missing seam added)"); - else if(sff->Status(ShapeExtend_DONE4)) - Msg::Info(" (small area wire removed)"); - else if(sff->Status(ShapeExtend_DONE5)) - Msg::Info(" (natural bounds added)"); - TopoDS_Face newface = sff->Face(); + // import all shapes in _maps into the GModel, preserving all explicit tags - rebuild->Replace(face, newface, Standard_False); - } + for(int i = 1; i <= _vmap.Extent(); i++){ + TopoDS_Vertex vertex = TopoDS::Vertex(_vmap(i)); + if(!getOCCVertexByNativePtr(model, vertex)){ + int tag; + if(_vertexTag.IsBound(vertex)){ + tag = _vertexTag.Find(vertex); } - myshape = rebuild->Apply(myshape); + else{ + tag = vTagMax + 1; + vTagMax++; + } + model->add(new OCCVertex(model, tag, vertex)); } + } - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); - for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if(BRep_Tool::Degenerated(edge)) - rebuild->Remove(edge, false); + // building geom edges + for(int i = 1; i <= _emap.Extent(); i++){ + TopoDS_Edge edge = TopoDS::Edge(_emap(i)); + if(!getOCCEdgeByNativePtr(model, edge)){ + GVertex *v1 = getOCCVertexByNativePtr(model, TopExp::FirstVertex(edge)); + GVertex *v2 = getOCCVertexByNativePtr(model, TopExp::LastVertex(edge)); + int tag; + if(_edgeTag.IsBound(edge)){ + tag = _edgeTag.Find(edge); } - myshape = rebuild->Apply(myshape); + else{ + tag = eTagMax + 1; + eTagMax++; + } + model->add(new OCCEdge(model, edge, tag, v1, v2)); } } - if(fixsmalledges){ - Msg::Info("- fixing small edges"); - - Handle(ShapeFix_Wire) sfw; - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); - - for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ - TopoDS_Face face = TopoDS::Face(exp0.Current()); - - for(exp1.Init(face, TopAbs_WIRE); exp1.More(); exp1.Next()){ - TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current()); - sfw = new ShapeFix_Wire(oldwire, face ,tolerance); - sfw->ModifyTopologyMode() = Standard_True; - - sfw->ClosedWireMode() = Standard_True; - - bool replace = false; - replace = sfw->FixReorder() || replace; - replace = sfw->FixConnected() || replace; - - if(sfw->FixSmall(Standard_False, tolerance) && - ! (sfw->StatusSmall(ShapeExtend_FAIL1) || - sfw->StatusSmall(ShapeExtend_FAIL2) || - sfw->StatusSmall(ShapeExtend_FAIL3))){ - Msg::Info(" fixed small edge in wire %d", _wmap.FindIndex(oldwire)); - replace = true; - } - else if(sfw->StatusSmall(ShapeExtend_FAIL1)) - Msg::Warning("Failed to fix small edge in wire %d, edge cannot be checked " - "(no 3d curve and no pcurve)", _wmap.FindIndex(oldwire)); - else if(sfw->StatusSmall(ShapeExtend_FAIL2)) - Msg::Warning("Failed to fix small edge in wire %d, " - "edge is null-length and has different vertives at begin and " - "end, and lockvtx is True or ModifiyTopologyMode is False", - _wmap.FindIndex(oldwire)); - else if(sfw->StatusSmall(ShapeExtend_FAIL3)) - Msg::Warning("Failed to fix small edge in wire, CheckConnected has failed", - _wmap.FindIndex(oldwire)); - - replace = sfw->FixEdgeCurves() || replace; - replace = sfw->FixDegenerated() || replace; - replace = sfw->FixSelfIntersection() || replace; - replace = sfw->FixLacking(Standard_True) || replace; - if(replace){ - TopoDS_Wire newwire = sfw->Wire(); - rebuild->Replace(oldwire, newwire, Standard_False); - } - } - } - - myshape = rebuild->Apply(myshape); - - { - buildLists(); - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); - - for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if(_vmap.FindIndex(TopExp::FirstVertex(edge)) == - _vmap.FindIndex(TopExp::LastVertex(edge))){ - GProp_GProps system; - BRepGProp::LinearProperties(edge, system); - if(system.Mass() < tolerance){ - Msg::Info(" removing degenerated edge %d from vertex %d to vertex %d", - _emap.FindIndex(edge), _vmap.FindIndex(TopExp::FirstVertex(edge)), - _vmap.FindIndex(TopExp::LastVertex(edge))); - rebuild->Remove(edge, false); - } - } - } - myshape = rebuild->Apply(myshape); - } - - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); - for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if(BRep_Tool::Degenerated(edge) ) - rebuild->Remove(edge, false); - } - myshape = rebuild->Apply(myshape); - } - - Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe; - sfwf->SetPrecision(tolerance); - sfwf->Load(myshape); - sfwf->ModeDropSmallEdges() = Standard_True; - - if(sfwf->FixWireGaps()){ - Msg::Info("- fixing wire gaps"); - if(sfwf->StatusWireGaps(ShapeExtend_OK)) - Msg::Info(" no gaps found"); - if(sfwf->StatusWireGaps(ShapeExtend_DONE1)) - Msg::Info(" some 2D gaps fixed"); - if(sfwf->StatusWireGaps(ShapeExtend_DONE2)) - Msg::Info(" some 3D gaps fixed"); - if(sfwf->StatusWireGaps(ShapeExtend_FAIL1)) - Msg::Info(" failed to fix some 2D gaps"); - if(sfwf->StatusWireGaps(ShapeExtend_FAIL2)) - Msg::Info(" failed to fix some 3D gaps"); - } - - sfwf->SetPrecision(tolerance); - - if(sfwf->FixSmallEdges()){ - Msg::Info("- fixing wire frames"); - if(sfwf->StatusSmallEdges(ShapeExtend_OK)) - Msg::Info(" no small edges found"); - if(sfwf->StatusSmallEdges(ShapeExtend_DONE1)) - Msg::Info(" some small edges fixed"); - if(sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) - Msg::Info(" failed to fix some small edges"); - } - - myshape = sfwf->Shape(); - } - - if(fixspotstripfaces){ - Msg::Info("- fixing spot and strip faces"); - Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace(); - sffsm->Init(myshape); - sffsm->SetPrecision(tolerance); - sffsm->Perform(); - - myshape = sffsm->FixShape(); - } - - if(sewfaces){ - Msg::Info("- sewing faces"); - - BRepOffsetAPI_Sewing sewedObj(tolerance); - - for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ - TopoDS_Face face = TopoDS::Face(exp0.Current()); - sewedObj.Add(face); - } - - sewedObj.Perform(); - - if(!sewedObj.SewedShape().IsNull()) - myshape = sewedObj.SewedShape(); - else - Msg::Info(" not possible"); - } - - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(myshape); - for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if(BRep_Tool::Degenerated(edge)) - rebuild->Remove(edge, false); - } - myshape = rebuild->Apply(myshape); - } - - if(makesolids){ - Msg::Info("- making solids"); - - BRepBuilderAPI_MakeSolid ms; - int count = 0; - for(exp0.Init(myshape, TopAbs_SHELL); exp0.More(); exp0.Next()){ - count++; - ms.Add(TopoDS::Shell(exp0.Current())); - } - - if(!count){ - Msg::Info(" not possible (no shells)"); - } - else{ - BRepCheck_Analyzer ba(ms); - if(ba.IsValid()){ - Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; - sfs->Init(ms); - sfs->SetPrecision(tolerance); - sfs->SetMaxTolerance(tolerance); - sfs->Perform(); - myshape = sfs->Shape(); - - for(exp0.Init(myshape, TopAbs_SOLID); exp0.More(); exp0.Next()){ - TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); - TopoDS_Solid newsolid = solid; - BRepLib::OrientClosedSolid(newsolid); - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - // rebuild->Apply(myshape); - rebuild->Replace(solid, newsolid, Standard_False); - TopoDS_Shape newshape = rebuild->Apply(myshape, TopAbs_COMPSOLID);//, 1); - // TopoDS_Shape newshape = rebuild->Apply(myshape); - myshape = newshape; - } - } - else - Msg::Info(" not possible"); - } - } - - double newsurfacecont = 0; - for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ - TopoDS_Face face = TopoDS::Face(exp0.Current()); - GProp_GProps system; - BRepGProp::SurfaceProperties(face, system); - newsurfacecont += system.Mass(); - } - - buildLists(); - int nnrc = 0, nnrcs = 0; - int nnrso = _somap.Extent(), nnrsh = _shmap.Extent(), nnrf = _fmap.Extent(); - int nnrw = _wmap.Extent(), nnre = _emap.Extent(), nnrv = _vmap.Extent(); - for(exp0.Init(myshape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nnrc++; - for(exp0.Init(myshape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nnrcs++; - - Msg::Info("-----------------------------------"); - Msg::Info("Compounds : %d (%d)", nnrc, nrc); - Msg::Info("Composite solids : %d (%d)", nnrcs, nrcs); - Msg::Info("Solids : %d (%d)", nnrso, nrso); - Msg::Info("Shells : %d (%d)", nnrsh, nrsh); - Msg::Info("Wires : %d (%d)", nnrw, nrw); - Msg::Info("Faces : %d (%d)", nnrf, nrf); - Msg::Info("Edges : %d (%d)", nnre, nre); - Msg::Info("Vertices : %d (%d)", nnrv, nrv ); - Msg::Info("Totol surface area : %g (%g)", newsurfacecont, surfacecont); - Msg::Info("-----------------------------------"); -} - -void OCC_Internals::importShapes(const std::string &fileName, - std::vector<int> outTags[4]) -{ - std::vector<std::string> split = SplitFileName(fileName); - TopoDS_Shape result; - try{ - if(split[2] == ".brep" || split[2] == ".BREP"){ - BRep_Builder aBuilder; - BRepTools::Read(result, fileName.c_str(), aBuilder); - } - else if(split[2] == ".step" || split[2] == ".stp" || - split[2] == ".STEP" || split[2] == ".STP"){ - STEPControl_Reader reader; - if(reader.ReadFile(fileName.c_str()) != IFSelect_RetDone){ - Msg::Error("Could not read file '%s'", fileName.c_str()); - return; - } - reader.TransferRoots(); - result = reader.OneShape(); - } - else{ - Msg::Error("Unknown file type '%s'", fileName.c_str()); - return; - } - // FIXME: apply healing routine on result? - } - catch(Standard_Failure &err){ - Msg::Error("OpenCASCADE exception %s", err.GetMessageString()); - return; - } - - TopExp_Explorer exp0; - for(exp0.Init(result, TopAbs_SOLID); exp0.More(); exp0.Next()){ - int t = getMaxTag(3) + 1; - bind(TopoDS::Solid(exp0.Current()), t); - outTags[3].push_back(t); - } - if(outTags[3].empty()){ - for(exp0.Init(result, TopAbs_FACE); exp0.More(); exp0.Next()){ - int t = getMaxTag(2) + 1; - bind(TopoDS::Face(exp0.Current()), t); - outTags[2].push_back(t); - } - } -} - -void OCC_Internals::exportShapes(const std::string &fileName) -{ - // iterate over all shapes with tags, and import them into the (sub)shape _maps - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp0(_tagVertex); - for(; exp0.More(); exp0.Next()) _addShapeToMaps(exp0.Value()); - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp1(_tagEdge); - for(; exp1.More(); exp1.Next()) _addShapeToMaps(exp1.Value()); - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp2(_tagFace); - for(; exp2.More(); exp2.Next()) _addShapeToMaps(exp2.Value()); - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp3(_tagSolid); - for(; exp3.More(); exp3.Next()) _addShapeToMaps(exp3.Value()); - - // build a single compound shape - BRep_Builder b; - TopoDS_Compound c; - b.MakeCompound(c); - for(int i = 1; i <= _vmap.Extent(); i++) b.Add(c, _vmap(i)); - for(int i = 1; i <= _emap.Extent(); i++) b.Add(c, _emap(i)); - for(int i = 1; i <= _wmap.Extent(); i++) b.Add(c, _wmap(i)); - for(int i = 1; i <= _fmap.Extent(); i++) b.Add(c, _fmap(i)); - for(int i = 1; i <= _shmap.Extent(); i++) b.Add(c, _shmap(i)); - for(int i = 1; i <= _somap.Extent(); i++) b.Add(c, _somap(i)); - - std::vector<std::string> split = SplitFileName(fileName); - - try { - if(split[2] == ".brep" || split[2] == ".BREP"){ - BRepTools::Write(c, fileName.c_str()); - } - else if(split[2] == ".step" || split[2] == ".stp" || - split[2] == ".STEP" || split[2] == ".STP"){ - STEPControl_Writer writer; - if(writer.Transfer(c, STEPControl_ManifoldSolidBrep) == IFSelect_RetDone){ - if(writer.Write(fileName.c_str()) != IFSelect_RetDone){ - Msg::Error("Could not create file '%s'", fileName.c_str()); - } + // building geom faces + for(int i = 1; i <= _fmap.Extent(); i++){ + TopoDS_Face face = TopoDS::Face(_fmap(i)); + if(!getOCCFaceByNativePtr(model, face)){ + int tag; + if(_faceTag.IsBound(face)){ + tag = _faceTag.Find(face); } else{ - Msg::Error("Could not create STEP data"); + tag = fTagMax + 1; + fTagMax++; } + model->add(new OCCFace(model, face, tag)); } } - catch(Standard_Failure &err){ - Msg::Error("OCC exception %s", err.GetMessageString()); + + // building geom regions + for(int i = 1; i <= _somap.Extent(); i++){ + TopoDS_Solid region = TopoDS::Solid(_somap(i)); + if(!getOCCRegionByNativePtr(model, region)){ + int tag; + if(_solidTag.IsBound(region)){ + tag = _solidTag(region); + } + else{ + tag = rTagMax + 1; + rTagMax++; + } + model->add(new OCCRegion(model, region, tag)); + } } } @@ -1150,116 +1021,373 @@ void OCC_Internals::_addShapeToMaps(TopoDS_Shape shape) _vmap.Add(vertex); } } - } + } + + // Free Vertices + for(exp5.Init(shape, TopAbs_VERTEX, TopAbs_EDGE); exp5.More(); exp5.Next()){ + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if(_vmap.FindIndex(vertex) < 1){ + _vmap.Add(vertex); + } + } +} + +void OCC_Internals::_healShape(TopoDS_Shape &myshape, double tolerance, + bool fixdegenerated, bool fixsmalledges, + bool fixspotstripfaces, bool sewfaces, + bool makesolids, double scaling) +{ + if(scaling != 1.0){ + Msg::Info("Scaling geometry by factor %g", scaling); + gp_Trsf t; + t.SetScaleFactor(scaling); + BRepBuilderAPI_Transform trsf(myshape, t); + myshape = trsf.Shape(); + } + + if(!fixdegenerated && !fixsmalledges && !fixspotstripfaces && + !sewfaces && !makesolids) return; + + Msg::Info("Starting shape healing (tolerance: %g)", tolerance); + + buildLists(); + TopExp_Explorer exp0, exp1; + int nrc = 0, nrcs = 0; + int nrso = _somap.Extent(), nrsh = _shmap.Extent(), nrf = _fmap.Extent(); + int nrw = _wmap.Extent(), nre = _emap.Extent(), nrv = _vmap.Extent(); + for(exp0.Init(myshape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++; + for(exp0.Init(myshape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++; + + double surfacecont = 0; + for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ + TopoDS_Face face = TopoDS::Face(exp0.Current()); + GProp_GProps system; + BRepGProp::SurfaceProperties(face, system); + surfacecont += system.Mass(); + } + + if(fixdegenerated){ + Msg::Info("- fix degenerated edges and faces"); + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if(BRep_Tool::Degenerated(edge)) + rebuild->Remove(edge, false); + } + myshape = rebuild->Apply(myshape); + } + buildLists(); + + { + Handle(ShapeFix_Face) sff; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + + for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + sff = new ShapeFix_Face(face); + sff->FixAddNaturalBoundMode() = Standard_True; + sff->FixSmallAreaWireMode() = Standard_True; + sff->Perform(); + + if(sff->Status(ShapeExtend_DONE1) || + sff->Status(ShapeExtend_DONE2) || + sff->Status(ShapeExtend_DONE3) || + sff->Status(ShapeExtend_DONE4) || + sff->Status(ShapeExtend_DONE5)) + { + Msg::Info(" repaired face %d", _fmap.FindIndex(face)); + if(sff->Status(ShapeExtend_DONE1)) + Msg::Info(" (some wires are fixed)"); + else if(sff->Status(ShapeExtend_DONE2)) + Msg::Info(" (orientation of wires fixed)"); + else if(sff->Status(ShapeExtend_DONE3)) + Msg::Info(" (missing seam added)"); + else if(sff->Status(ShapeExtend_DONE4)) + Msg::Info(" (small area wire removed)"); + else if(sff->Status(ShapeExtend_DONE5)) + Msg::Info(" (natural bounds added)"); + TopoDS_Face newface = sff->Face(); + + rebuild->Replace(face, newface, Standard_False); + } + } + myshape = rebuild->Apply(myshape); + } + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if(BRep_Tool::Degenerated(edge)) + rebuild->Remove(edge, false); + } + myshape = rebuild->Apply(myshape); + } + } + + if(fixsmalledges){ + Msg::Info("- fixing small edges"); + + Handle(ShapeFix_Wire) sfw; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + + for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + for(exp1.Init(face, TopAbs_WIRE); exp1.More(); exp1.Next()){ + TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current()); + sfw = new ShapeFix_Wire(oldwire, face ,tolerance); + sfw->ModifyTopologyMode() = Standard_True; + + sfw->ClosedWireMode() = Standard_True; + + bool replace = false; + replace = sfw->FixReorder() || replace; + replace = sfw->FixConnected() || replace; + + if(sfw->FixSmall(Standard_False, tolerance) && + ! (sfw->StatusSmall(ShapeExtend_FAIL1) || + sfw->StatusSmall(ShapeExtend_FAIL2) || + sfw->StatusSmall(ShapeExtend_FAIL3))){ + Msg::Info(" fixed small edge in wire %d", _wmap.FindIndex(oldwire)); + replace = true; + } + else if(sfw->StatusSmall(ShapeExtend_FAIL1)) + Msg::Warning("Failed to fix small edge in wire %d, edge cannot be checked " + "(no 3d curve and no pcurve)", _wmap.FindIndex(oldwire)); + else if(sfw->StatusSmall(ShapeExtend_FAIL2)) + Msg::Warning("Failed to fix small edge in wire %d, " + "edge is null-length and has different vertives at begin and " + "end, and lockvtx is True or ModifiyTopologyMode is False", + _wmap.FindIndex(oldwire)); + else if(sfw->StatusSmall(ShapeExtend_FAIL3)) + Msg::Warning("Failed to fix small edge in wire, CheckConnected has failed", + _wmap.FindIndex(oldwire)); + + replace = sfw->FixEdgeCurves() || replace; + replace = sfw->FixDegenerated() || replace; + replace = sfw->FixSelfIntersection() || replace; + replace = sfw->FixLacking(Standard_True) || replace; + if(replace){ + TopoDS_Wire newwire = sfw->Wire(); + rebuild->Replace(oldwire, newwire, Standard_False); + } + } + } + + myshape = rebuild->Apply(myshape); + + { + buildLists(); + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + + for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if(_vmap.FindIndex(TopExp::FirstVertex(edge)) == + _vmap.FindIndex(TopExp::LastVertex(edge))){ + GProp_GProps system; + BRepGProp::LinearProperties(edge, system); + if(system.Mass() < tolerance){ + Msg::Info(" removing degenerated edge %d from vertex %d to vertex %d", + _emap.FindIndex(edge), _vmap.FindIndex(TopExp::FirstVertex(edge)), + _vmap.FindIndex(TopExp::LastVertex(edge))); + rebuild->Remove(edge, false); + } + } + } + myshape = rebuild->Apply(myshape); + } + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if(BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + myshape = rebuild->Apply(myshape); + } + + Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe; + sfwf->SetPrecision(tolerance); + sfwf->Load(myshape); + sfwf->ModeDropSmallEdges() = Standard_True; + + if(sfwf->FixWireGaps()){ + Msg::Info("- fixing wire gaps"); + if(sfwf->StatusWireGaps(ShapeExtend_OK)) + Msg::Info(" no gaps found"); + if(sfwf->StatusWireGaps(ShapeExtend_DONE1)) + Msg::Info(" some 2D gaps fixed"); + if(sfwf->StatusWireGaps(ShapeExtend_DONE2)) + Msg::Info(" some 3D gaps fixed"); + if(sfwf->StatusWireGaps(ShapeExtend_FAIL1)) + Msg::Info(" failed to fix some 2D gaps"); + if(sfwf->StatusWireGaps(ShapeExtend_FAIL2)) + Msg::Info(" failed to fix some 3D gaps"); + } + + sfwf->SetPrecision(tolerance); + + if(sfwf->FixSmallEdges()){ + Msg::Info("- fixing wire frames"); + if(sfwf->StatusSmallEdges(ShapeExtend_OK)) + Msg::Info(" no small edges found"); + if(sfwf->StatusSmallEdges(ShapeExtend_DONE1)) + Msg::Info(" some small edges fixed"); + if(sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) + Msg::Info(" failed to fix some small edges"); + } - // Free Vertices - for(exp5.Init(shape, TopAbs_VERTEX, TopAbs_EDGE); exp5.More(); exp5.Next()){ - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if(_vmap.FindIndex(vertex) < 1){ - _vmap.Add(vertex); - } + myshape = sfwf->Shape(); } -} -void OCC_Internals::synchronize(GModel *model) -{ - int vTagMax = std::max(model->getMaxElementaryNumber(0), getMaxTag(0)); - int eTagMax = std::max(model->getMaxElementaryNumber(1), getMaxTag(1)); - int fTagMax = std::max(model->getMaxElementaryNumber(2), getMaxTag(2)); - int rTagMax = std::max(model->getMaxElementaryNumber(3), getMaxTag(3)); + if(fixspotstripfaces){ + Msg::Info("- fixing spot and strip faces"); + Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace(); + sffsm->Init(myshape); + sffsm->SetPrecision(tolerance); + sffsm->Perform(); - _somap.Clear(); - _shmap.Clear(); - _fmap.Clear(); - _wmap.Clear(); - _emap.Clear(); - _vmap.Clear(); + myshape = sffsm->FixShape(); + } - // iterate over all shapes with tags, and import them into the (sub)shape _maps - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp0(_tagVertex); - for(; exp0.More(); exp0.Next()) _addShapeToMaps(exp0.Value()); - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp1(_tagEdge); - for(; exp1.More(); exp1.Next()) _addShapeToMaps(exp1.Value()); - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp2(_tagFace); - for(; exp2.More(); exp2.Next()) _addShapeToMaps(exp2.Value()); - TopTools_DataMapIteratorOfDataMapOfIntegerShape exp3(_tagSolid); - for(; exp3.More(); exp3.Next()) _addShapeToMaps(exp3.Value()); + if(sewfaces){ + Msg::Info("- sewing faces"); - // import all shapes in _maps into the GModel, preserving all explicit tags + BRepOffsetAPI_Sewing sewedObj(tolerance); - for(int i = 1; i <= _vmap.Extent(); i++){ - TopoDS_Vertex vertex = TopoDS::Vertex(_vmap(i)); - if(!getOCCVertexByNativePtr(model, vertex)){ - int tag; - if(_vertexTag.IsBound(vertex)){ - tag = _vertexTag.Find(vertex); - } - else{ - tag = vTagMax + 1; - vTagMax++; - } - model->add(new OCCVertex(model, tag, vertex)); + for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ + TopoDS_Face face = TopoDS::Face(exp0.Current()); + sewedObj.Add(face); } + + sewedObj.Perform(); + + if(!sewedObj.SewedShape().IsNull()) + myshape = sewedObj.SewedShape(); + else + Msg::Info(" not possible"); } - // building geom edges - for(int i = 1; i <= _emap.Extent(); i++){ - TopoDS_Edge edge = TopoDS::Edge(_emap(i)); - if(!getOCCEdgeByNativePtr(model, edge)){ - GVertex *v1 = getOCCVertexByNativePtr(model, TopExp::FirstVertex(edge)); - GVertex *v2 = getOCCVertexByNativePtr(model, TopExp::LastVertex(edge)); - int tag; - if(_edgeTag.IsBound(edge)){ - tag = _edgeTag.Find(edge); - } - else{ - tag = eTagMax + 1; - eTagMax++; - } - model->add(new OCCEdge(model, edge, tag, v1, v2)); + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(myshape); + for(exp1.Init(myshape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if(BRep_Tool::Degenerated(edge)) + rebuild->Remove(edge, false); } + myshape = rebuild->Apply(myshape); } - // building geom faces - for(int i = 1; i <= _fmap.Extent(); i++){ - TopoDS_Face face = TopoDS::Face(_fmap(i)); - if(!getOCCFaceByNativePtr(model, face)){ - int tag; - if(_faceTag.IsBound(face)){ - tag = _faceTag.Find(face); - } - else{ - tag = fTagMax + 1; - fTagMax++; - } - model->add(new OCCFace(model, face, tag)); + if(makesolids){ + Msg::Info("- making solids"); + + BRepBuilderAPI_MakeSolid ms; + int count = 0; + for(exp0.Init(myshape, TopAbs_SHELL); exp0.More(); exp0.Next()){ + count++; + ms.Add(TopoDS::Shell(exp0.Current())); } - } - // building geom regions - for(int i = 1; i <= _somap.Extent(); i++){ - TopoDS_Solid region = TopoDS::Solid(_somap(i)); - if(!getOCCRegionByNativePtr(model, region)){ - int tag; - if(_solidTag.IsBound(region)){ - tag = _solidTag(region); - } - else{ - tag = rTagMax + 1; - rTagMax++; + if(!count){ + Msg::Info(" not possible (no shells)"); + } + else{ + BRepCheck_Analyzer ba(ms); + if(ba.IsValid()){ + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init(ms); + sfs->SetPrecision(tolerance); + sfs->SetMaxTolerance(tolerance); + sfs->Perform(); + myshape = sfs->Shape(); + + for(exp0.Init(myshape, TopAbs_SOLID); exp0.More(); exp0.Next()){ + TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); + TopoDS_Solid newsolid = solid; + BRepLib::OrientClosedSolid(newsolid); + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + // rebuild->Apply(myshape); + rebuild->Replace(solid, newsolid, Standard_False); + TopoDS_Shape newshape = rebuild->Apply(myshape, TopAbs_COMPSOLID);//, 1); + // TopoDS_Shape newshape = rebuild->Apply(myshape); + myshape = newshape; + } } - model->add(new OCCRegion(model, region, tag)); + else + Msg::Info(" not possible"); } } + + double newsurfacecont = 0; + for(exp0.Init(myshape, TopAbs_FACE); exp0.More(); exp0.Next()){ + TopoDS_Face face = TopoDS::Face(exp0.Current()); + GProp_GProps system; + BRepGProp::SurfaceProperties(face, system); + newsurfacecont += system.Mass(); + } + + buildLists(); + int nnrc = 0, nnrcs = 0; + int nnrso = _somap.Extent(), nnrsh = _shmap.Extent(), nnrf = _fmap.Extent(); + int nnrw = _wmap.Extent(), nnre = _emap.Extent(), nnrv = _vmap.Extent(); + for(exp0.Init(myshape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nnrc++; + for(exp0.Init(myshape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nnrcs++; + + Msg::Info("-----------------------------------"); + Msg::Info("Compounds : %d (%d)", nnrc, nrc); + Msg::Info("Composite solids : %d (%d)", nnrcs, nrcs); + Msg::Info("Solids : %d (%d)", nnrso, nrso); + Msg::Info("Shells : %d (%d)", nnrsh, nrsh); + Msg::Info("Wires : %d (%d)", nnrw, nrw); + Msg::Info("Faces : %d (%d)", nnrf, nrf); + Msg::Info("Edges : %d (%d)", nnre, nre); + Msg::Info("Vertices : %d (%d)", nnrv, nrv ); + Msg::Info("Totol surface area : %g (%g)", newsurfacecont, surfacecont); + Msg::Info("-----------------------------------"); } -int GModel::importOCCInternals() +GVertex *OCC_Internals::getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind) { - _occ_internals->synchronize(this); - return 1; + if(_vertexTag.IsBound(toFind)) + return model->getVertexByTag(_vertexTag.Find(toFind)); + return 0; +} + +GEdge *OCC_Internals::getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind) +{ + if(_edgeTag.IsBound(toFind)) + return model->getEdgeByTag(_edgeTag.Find(toFind)); + return 0; +} + +GFace *OCC_Internals::getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind) +{ + if(_faceTag.IsBound(toFind)) + return model->getFaceByTag(_faceTag.Find(toFind)); + return 0; +} + +GRegion *OCC_Internals::getOCCRegionByNativePtr(GModel *model, TopoDS_Solid toFind) +{ + if(_solidTag.IsBound(toFind)) + return model->getRegionByTag(_solidTag.Find(toFind)); + return 0; } + // FIXME ***************** old ************************ void addSimpleShapes(TopoDS_Shape theShape, TopTools_ListOfShape &theList) @@ -1404,41 +1532,6 @@ void OCC_Internals::loadIGES(const char *fn) buildLists(); } -void OCC_Internals::loadShape(const TopoDS_Shape *s) -{ - _shape = *s; - BRepTools::Clean(_shape); - buildLists(); -} - -GVertex *OCC_Internals::getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind) -{ - if(_vertexTag.IsBound(toFind)) - return model->getVertexByTag(_vertexTag.Find(toFind)); - return 0; -} - -GEdge *OCC_Internals::getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind) -{ - if(_edgeTag.IsBound(toFind)) - return model->getEdgeByTag(_edgeTag.Find(toFind)); - return 0; -} - -GFace *OCC_Internals::getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind) -{ - if(_faceTag.IsBound(toFind)) - return model->getFaceByTag(_faceTag.Find(toFind)); - return 0; -} - -GRegion *OCC_Internals::getOCCRegionByNativePtr(GModel *model, TopoDS_Solid toFind) -{ - if(_solidTag.IsBound(toFind)) - return model->getRegionByTag(_solidTag.Find(toFind)); - return 0; -} - GVertex *OCC_Internals::addVertexToModel(GModel *model, TopoDS_Vertex vertex) { GVertex *gv = getOCCVertexByNativePtr(model, vertex); @@ -1530,7 +1623,6 @@ void OCC_Internals::buildGModel(GModel *model) } } - void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperator &op) { if(tool.IsNull()) return; @@ -1779,6 +1871,12 @@ void GModel::_deleteOCCInternals() _occ_internals = 0; } +int GModel::importOCCInternals() +{ + _occ_internals->synchronize(this); + return 1; +} + int GModel::readOCCBREP(const std::string &fn) { _occ_internals = new OCC_Internals; @@ -1829,8 +1927,9 @@ int GModel::importOCCShape(const void *shape) { if(!_occ_internals) _occ_internals = new OCC_Internals; - _occ_internals->loadShape((TopoDS_Shape*)shape); - _occ_internals->buildGModel(this); + std::vector<int> tags[4]; + _occ_internals->importShapes((TopoDS_Shape*)shape, tags); + _occ_internals->synchronize(this); snapVertices(); SetBoundingBox(); return 1; @@ -1870,74 +1969,74 @@ void GModel::_deleteOCCInternals() { } +int GModel::importOCCInternals() +{ + return 0; +} + int GModel::readOCCBREP(const std::string &fn) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to load '%s'", + Msg::Error("Gmsh must be compiled with OpenCASCADE support to load '%s'", fn.c_str()); return 0; } int GModel::readOCCSTEP(const std::string &fn) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to load '%s'", + Msg::Error("Gmsh must be compiled with OpenCASCADE support to load '%s'", fn.c_str()); return 0; } int GModel::readOCCIGES(const std::string &fn) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to load '%s'", + Msg::Error("Gmsh must be compiled with OpenCASCADE support to load '%s'", fn.c_str()); return 0; } int GModel::writeOCCBREP(const std::string &fn) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to write '%s'", + Msg::Error("Gmsh must be compiled with OpenCASCADE support to write '%s'", fn.c_str()); return 0; } int GModel::writeOCCSTEP(const std::string &fn) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to write '%s'", + Msg::Error("Gmsh must be compiled with OpenCASCADE support to write '%s'", fn.c_str()); return 0; } int GModel::importOCCShape(const void *shape) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to import " + Msg::Error("Gmsh must be compiled with OpenCASCADE support to import " "a TopoDS_Shape"); return 0; } GVertex* GModel::getVertexForOCCShape(const void *shape) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to query OCC shape"); + Msg::Error("Gmsh must be compiled with OpenCASCADE support to query OCC shape"); return 0; } GEdge* GModel::getEdgeForOCCShape(const void *shape) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to query OCC shape"); + Msg::Error("Gmsh must be compiled with OpenCASCADE support to query OCC shape"); return 0; } GFace* GModel::getFaceForOCCShape(const void *shape) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to query OCC shape"); + Msg::Error("Gmsh must be compiled with OpenCASCADE support to query OCC shape"); return 0; } GRegion* GModel::getRegionForOCCShape(const void *shape) { - Msg::Error("Gmsh must be compiled with Open CASCADE support to query OCC shape"); - return 0; -} - -int GModel::importOCCInternals() -{ + Msg::Error("Gmsh must be compiled with OpenCASCADE support to query OCC shape"); return 0; } diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h index e8675f75a28a7b4a415ff7ec3347e1269c402f4f..a9d27e6d3fb0a9740cd0486a972aba017972cb5e 100644 --- a/Geo/GModelIO_OCC.h +++ b/Geo/GModelIO_OCC.h @@ -44,11 +44,11 @@ class OCC_Internals { bool fixsmalledges, bool fixspotstripfaces, bool sewfaces, bool makesolids=false, double scaling=0.0); - protected : + // *** FIXME will be removed *** + protected : TopoDS_Shape _shape; public: - // *** FIXME: will be removed with GModelFactory *** void _addShapeToLists(TopoDS_Shape shape){ _addShapeToMaps(shape); } void _healGeometry(double tolerance, bool fixdegenerated, bool fixsmalledges, bool fixspotstripfaces, bool sewfaces, @@ -67,20 +67,34 @@ class OCC_Internals { void loadBREP(const char *); void loadSTEP(const char *); void loadIGES(const char *); - void loadShape(const TopoDS_Shape *); - // *** end of stuff that will be removed *** - - public: - OCC_Internals() + void loadShape(const TopoDS_Shape *s) { - for(int i = 0; i < 4; i++) _maxTagConstraints[i] = 0; + std::vector<int> tags[4]; importShapes(s, tags); } + // *** FIXME end of stuff that will be removed *** + + public: + OCC_Internals(); + + // bind and unbind OpenCASCADE shapes to tags + void bind(TopoDS_Vertex vertex, int tag); + void bind(TopoDS_Edge edge, int tag); + void bind(TopoDS_Wire wire, int tag); + void bind(TopoDS_Face face, int tag); + void bind(TopoDS_Shell shell, int tag); + void bind(TopoDS_Solid solid, int tag); + void unbind(TopoDS_Vertex vertex, int tag); + void unbind(TopoDS_Edge edge, int tag); + void unbind(TopoDS_Wire wire, int tag); + void unbind(TopoDS_Face face, int tag); + void unbind(TopoDS_Shell shell, int tag); + void unbind(TopoDS_Solid solid, int tag); + + // bind highest-dimensional entities in shape to tags + void bindHighest(TopoDS_Shape shape, std::vector<int> tags[4]); // set constraints on tags - void setTagConstraints(int maxTags[4]) - { - for(int i = 0; i < 4; i++) _maxTagConstraints[i] = maxTags[i]; - } + void setTagConstraints(int maxTags[4]); // get maximum tag number for each dimension int getMaxTag(int dim) const; @@ -114,73 +128,15 @@ class OCC_Internals { // import shapes from file void importShapes(const std::string &fileName, std::vector<int> outTags[4]); + // import shapes from TopoDS_Shape + void importShapes(const TopoDS_Shape *shape, std::vector<int> outTags[4]); + // export all tagged shapes to file void exportShapes(const std::string &fileName); // synchronize all shapes in maps with the given GModel void synchronize(GModel *model); - // bind and unbind OpenCASCADE shapes to tags - void bind(TopoDS_Vertex vertex, int tag) - { - _vertexTag.Bind(vertex, tag); - _tagVertex.Bind(tag, vertex); - } - void bind(TopoDS_Edge edge, int tag) - { - _edgeTag.Bind(edge, tag); - _tagEdge.Bind(tag, edge); - } - void bind(TopoDS_Wire wire, int tag) - { - _wireTag.Bind(wire, tag); - _tagWire.Bind(tag, wire); - } - void bind(TopoDS_Face face, int tag) - { - _faceTag.Bind(face, tag); - _tagFace.Bind(tag, face); - } - void bind(TopoDS_Shell shell, int tag) - { - _shellTag.Bind(shell, tag); - _tagShell.Bind(tag, shell); - } - void bind(TopoDS_Solid solid, int tag) - { - _solidTag.Bind(solid, tag); - _tagSolid.Bind(tag, solid); - } - void unbind(TopoDS_Vertex vertex, int tag) - { - _vertexTag.UnBind(vertex); - _tagVertex.UnBind(tag); - } - void unbind(TopoDS_Edge edge, int tag) - { - _edgeTag.UnBind(edge); - _tagEdge.UnBind(tag); - } - void unbind(TopoDS_Wire wire, int tag) - { - _wireTag.UnBind(wire); - _tagWire.UnBind(tag); - } - void unbind(TopoDS_Face face, int tag) - { - _faceTag.UnBind(face); - _tagFace.UnBind(tag); - } - void unbind(TopoDS_Shell shell, int tag) - { - _shellTag.UnBind(shell); - _tagShell.UnBind(tag); - } - void unbind(TopoDS_Solid solid, int tag) - { - _solidTag.UnBind(solid); - _tagSolid.UnBind(tag); - } GVertex *getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind); GEdge *getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind); GFace *getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind);