1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-30 12:14:08 +03:00
occt/src/ShapeUpgrade/ShapeUpgrade_RemoveLocations.cxx
abv 92efcf78a6 0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
Automatic restore of IMPLEMENT_STANDARD_RTTIEXT macro (upgrade -rtti)
2015-12-04 14:15:06 +03:00

288 lines
10 KiB
C++

// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRep_Builder.hxx>
#include <BRep_CurveRepresentation.hxx>
#include <BRep_GCurve.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_Tool.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Geometry.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <ShapeBuild_Edge.hxx>
#include <ShapeUpgrade_RemoveLocations.hxx>
#include <Standard_Type.hxx>
#include <TColStd_ListIteratorOfListOfTransient.hxx>
#include <TColStd_ListOfTransient.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_RemoveLocations,MMgt_TShared)
//#include <ShapeUpgrade_DataMapOfShapeListOfTransient.hxx>
//=======================================================================
//function : ShapeUpgrade_RemoveLocations
//purpose :
//=======================================================================
ShapeUpgrade_RemoveLocations::ShapeUpgrade_RemoveLocations()
{
myLevelRemoving = TopAbs_SHAPE;
}
//=======================================================================
//function : Remove
//purpose :
//=======================================================================
Standard_Boolean ShapeUpgrade_RemoveLocations::Remove(const TopoDS_Shape& theShape)
{
TopoDS_Shape aShape = theShape;
myShape = aShape;
TopAbs_ShapeEnum shtype = theShape.ShapeType();
Standard_Boolean isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
TopoDS_Shape S;
Standard_Boolean isDone = MakeNewShape(theShape,S,myShape,isRemoveLoc);
return isDone;
}
//=======================================================================
//function : RebuildShape
//purpose :
//=======================================================================
static Standard_Boolean RebuildShape(const TopoDS_Face& theFace, TopoDS_Face& theNewFace)
{
BRep_Builder aB;
TopLoc_Location aLoc;
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace,aLoc);
Standard_Boolean isRebuild = Standard_False;
if(!aLoc.IsIdentity()) {
Handle(Geom_Surface) anewSurf =Handle(Geom_Surface)::DownCast( aSurf->Transformed(aLoc.Transformation()));
aB.MakeFace(theNewFace,anewSurf,BRep_Tool::Tolerance(theFace));
isRebuild = Standard_True;
}
return isRebuild;
}
//=======================================================================
//function : RebuildShape
//purpose :
//=======================================================================
static Standard_Boolean RebuildShape(const TopoDS_Edge& theEdge, TopoDS_Edge& theNewEdge,
const TopoDS_Face& theFace, TopoDS_Face& theNewFace,
Standard_Boolean isBound)
{
Standard_Boolean isRebuild = Standard_False;
BRep_Builder aB;
if(!isBound) {
Handle(Geom_Curve) C3d;
TopLoc_Location aLoc;
Standard_Real First3d,Last3d;
C3d = BRep_Tool::Curve( theEdge,aLoc,First3d,Last3d);
aB.MakeEdge(theNewEdge);
if(!C3d.IsNull()) {
if(!aLoc.IsIdentity()) {
Handle(Geom_Curve) anewC3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(aLoc.Transformation()));
C3d = anewC3d;
}
aB.UpdateEdge(theNewEdge,C3d,BRep_Tool::Tolerance(theEdge));
aB.Range(theNewEdge,First3d,Last3d);
}
theNewEdge.Orientation(theEdge.Orientation());
if(BRep_Tool::Degenerated(theEdge))
aB.Degenerated(theNewEdge,Standard_True);
isRebuild = Standard_True;
}
if(!theFace.IsNull()) {
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
if(!aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
Handle(Geom2d_Curve) c2d,c2d1;
Standard_Real First2d,Last2d;
c2d= BRep_Tool::CurveOnSurface( theEdge,theFace,First2d,Last2d);
if(BRep_Tool::IsClosed(theEdge,theFace)) {
if(!BRep_Tool::IsClosed(theNewEdge,theNewFace)) {
TopoDS_Edge tmpE = TopoDS::Edge(theEdge.Reversed());
c2d1= BRep_Tool::CurveOnSurface(tmpE,theFace,First2d,Last2d);
TopAbs_Orientation OrEdge = theNewEdge.Orientation();
if(theFace.Orientation() == TopAbs_REVERSED)
OrEdge = ( OrEdge == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
if(OrEdge == TopAbs_FORWARD)
aB.UpdateEdge(theNewEdge,c2d, c2d1,theNewFace,0);
else aB.UpdateEdge(theNewEdge,c2d1, c2d,theNewFace,0);
}
}
else
aB.UpdateEdge(theNewEdge,c2d,theNewFace,0);
if(!c2d.IsNull() || !c2d1.IsNull())
aB.Range(theNewEdge,theNewFace,First2d,Last2d);
}
}
return isRebuild;
}
//=======================================================================
//function : RebuildShape
//purpose :
//=======================================================================
static Standard_Boolean RebuildShape(const TopoDS_Vertex& theVertex, TopoDS_Vertex& theNewVertex)
{
BRep_Builder aB;
aB.MakeVertex(theNewVertex);
theNewVertex.Orientation( theVertex.Orientation());
gp_Pnt p1 = BRep_Tool::Pnt( theVertex);
aB.UpdateVertex(theNewVertex,p1,BRep_Tool::Tolerance( theVertex));
return Standard_True;
}
//=======================================================================
//function : MakeNewShape
//purpose :
//=======================================================================
Standard_Boolean ShapeUpgrade_RemoveLocations::MakeNewShape(const TopoDS_Shape& theShape,
const TopoDS_Shape& theAncShape,
TopoDS_Shape& theNewShape,
const Standard_Boolean theRemoveLoc)
{
Standard_Boolean isDone = Standard_False;
TopoDS_Shape aNewShape;
TopAbs_ShapeEnum shtype = theShape.ShapeType();
BRep_Builder aB;
TopoDS_Shape aShape = theShape;
if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
TopLoc_Location nulLoc;
aShape.Location(nulLoc);
}
Standard_Boolean isBound = myMapNewShapes.IsBound(aShape);
if(isBound) {
aNewShape= myMapNewShapes.Find(aShape);
aNewShape.Orientation(theShape.Orientation());
if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
TopLoc_Location aL = theShape.Location();
aNewShape.Location(aL);
}
if(shtype != TopAbs_EDGE) {
theNewShape = aNewShape;
return Standard_True;
}
}
Standard_Boolean isRemoveLoc = theRemoveLoc;
if(!theRemoveLoc) {
isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
}
Standard_Boolean aRebuild = Standard_False;
TopoDS_Shape anAncShape = theAncShape;
if(shtype == TopAbs_FACE)
anAncShape = aShape;
if(isRemoveLoc && (!aShape.Location().IsIdentity() || shtype == TopAbs_EDGE || shtype == TopAbs_FACE )) {
//Rebuild geometry for shape with location.
if(shtype == TopAbs_FACE) {
TopoDS_Face anewFace;
TopoDS_Face oldFace = TopoDS::Face(aShape);
aRebuild = RebuildShape(oldFace,anewFace);
if(aRebuild) {
aNewShape = anewFace;
myMapNewShapes.Bind(oldFace,aNewShape);
}
}
else if(shtype == TopAbs_EDGE) {
TopoDS_Edge oldEdge = TopoDS::Edge(aShape);
TopoDS_Edge anewEdge;
TopoDS_Face F,newFace;
if(!anAncShape.IsNull()) {
F = TopoDS::Face(anAncShape);
newFace = F;
if(myMapNewShapes.IsBound(F))
newFace = TopoDS::Face(myMapNewShapes.Find(F));
}
if(isBound)
anewEdge = TopoDS::Edge(aNewShape);
aRebuild = RebuildShape(oldEdge,anewEdge,F,newFace,isBound);
aNewShape = anewEdge;
}
else if(shtype == TopAbs_VERTEX) {
TopoDS_Vertex aVnew;
TopoDS_Vertex aV = TopoDS::Vertex(aShape);
aRebuild = RebuildShape(aV,aVnew);
if(aRebuild)
aNewShape = aVnew;
}
}
isDone = aRebuild;
//Removing location from sub-shapes in dependance of LevelRemoving and re-building shape.
if(!isBound) {
if(!aRebuild)
{
aNewShape = theShape.EmptyCopied();
// it is safe to simply copy Closed flag since this operation does not change topology
aNewShape.Closed (theShape.Closed());
}
TopLoc_Location oldLoc,nullloc;
oldLoc = theShape.Location();
if(!oldLoc.IsIdentity())
aNewShape.Location(nullloc);
TopAbs_Orientation orient = theShape.Orientation();
aNewShape.Orientation(TopAbs_FORWARD);
TopoDS_Iterator aIt(aShape,Standard_False,isRemoveLoc);
for( ; aIt.More(); aIt.Next()) {
TopoDS_Shape subshape = aIt.Value();
TopoDS_Shape anewsubshape;
Standard_Boolean isDoneSubShape = MakeNewShape(subshape,anAncShape,anewsubshape,isRemoveLoc);
isDone = (isDone || isDoneSubShape);
aB.Add(aNewShape,anewsubshape);
}
if(isDone)
aNewShape.Orientation(orient);
else
aNewShape = aShape;
myMapNewShapes.Bind(aShape,aNewShape);
if(!theRemoveLoc && !oldLoc.IsIdentity())
aNewShape.Location(oldLoc);
}
theNewShape = aNewShape;
return (isDone || isBound);
}