Loading files
4f95ecaa3This file is pinned to the selected release. Download the original to open it in your design tool.
// 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_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 <ShapeUpgrade_RemoveLocations.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp.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>
IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_RemoveLocations, Standard_Transient)
// #include <ShapeUpgrade_DataMapOfShapeListOfTransient.hxx>
//=================================================================================================
ShapeUpgrade_RemoveLocations::ShapeUpgrade_RemoveLocations()
{
myLevelRemoving = TopAbs_SHAPE;
}
//=================================================================================================
bool ShapeUpgrade_RemoveLocations::Remove(const TopoDS_Shape& theShape)
{
const TopoDS_Shape& aShape = theShape;
myShape = aShape;
TopAbs_ShapeEnum shtype = theShape.ShapeType();
bool isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE)
|| ((int)myLevelRemoving <= ((int)shtype)));
TopoDS_Shape S;
bool isDone = MakeNewShape(theShape, S, myShape, isRemoveLoc);
return isDone;
}
//=================================================================================================
static bool RebuildShape(const TopoDS_Face& theFace, TopoDS_Face& theNewFace)
{
BRep_Builder aB;
TopLoc_Location aLoc;
occ::handle<Geom_Surface> aSurf = BRep_Tool::Surface(theFace, aLoc);
bool isRebuild = false;
if (!aLoc.IsIdentity())
{
occ::handle<Geom_Surface> anewSurf =
occ::down_cast<Geom_Surface>(aSurf->Transformed(aLoc.Transformation()));
aB.MakeFace(theNewFace, anewSurf, BRep_Tool::Tolerance(theFace));
isRebuild = true;
}
return isRebuild;
}
//=================================================================================================
static bool RebuildShape(const TopoDS_Edge& theEdge,
TopoDS_Edge& theNewEdge,
const TopoDS_Face& theFace,
TopoDS_Face& theNewFace,
bool isBound)
{
bool isRebuild = false;
BRep_Builder aB;
if (!isBound)
{
occ::handle<Geom_Curve> C3d;
TopLoc_Location aLoc;
double First3d, Last3d;
C3d = BRep_Tool::Curve(theEdge, aLoc, First3d, Last3d);
aB.MakeEdge(theNewEdge);
if (!C3d.IsNull())
{
if (!aLoc.IsIdentity())
{
occ::handle<Geom_Curve> anewC3d =
occ::down_cast<Geom_Curve>(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, true);
}
isRebuild = true;
}
if (!theFace.IsNull())
{
occ::handle<Geom_Surface> aSurf = BRep_Tool::Surface(theFace);
if (!aSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
{
occ::handle<Geom2d_Curve> c2d, c2d1;
double 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;
}
//=================================================================================================
static bool 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 true;
}
//=================================================================================================
bool ShapeUpgrade_RemoveLocations::MakeNewShape(const TopoDS_Shape& theShape,
const TopoDS_Shape& theAncShape,
TopoDS_Shape& theNewShape,
const bool theRemoveLoc)
{
bool isDone = 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);
}
bool isBound = myMapNewShapes.IsBound(aShape);
if (isBound)
{
aNewShape = myMapNewShapes.Find(aShape);
aNewShape.Orientation(theShape.Orientation());
if (!theRemoveLoc && !theShape.Location().IsIdentity())
{
const TopLoc_Location& aL = theShape.Location();
aNewShape.Location(aL);
}
if (shtype != TopAbs_EDGE)
{
theNewShape = aNewShape;
return true;
}
}
bool isRemoveLoc = theRemoveLoc;
if (!theRemoveLoc)
{
isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE)
|| ((int)myLevelRemoving <= ((int)shtype)));
}
bool aRebuild = 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 dependence 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, false, isRemoveLoc);
for (; aIt.More(); aIt.Next())
{
const TopoDS_Shape& subshape = aIt.Value();
TopoDS_Shape anewsubshape;
bool 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);
}