1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0024876: Add protection of shapes against modification of geometry

Added flag "locked" for protection of geometric data in the shapes (including tolerances).
Modification test case to avoid regression.
This commit is contained in:
ink 2014-07-10 14:42:12 +04:00 committed by apn
parent 01a6e62bc2
commit ebfb9ce298
8 changed files with 326 additions and 9 deletions

View File

@ -30,6 +30,7 @@
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_LockedShape.hxx>
#include <Precision.hxx>
@ -424,6 +425,10 @@ void BRep_Builder::MakeFace(TopoDS_Face& F,
const Standard_Real Tol) const
{
Handle(BRep_TFace) TF = new BRep_TFace();
if(!F.IsNull() && F.Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::MakeFace");
}
TF->Surface(S);
TF->Tolerance(Tol);
MakeShape(F,TF);
@ -439,6 +444,10 @@ void BRep_Builder::MakeFace(TopoDS_Face& F,
const Handle(Poly_Triangulation)& T) const
{
Handle(BRep_TFace) TF = new BRep_TFace();
if(!F.IsNull() && F.Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::MakeFace");
}
TF->Triangulation(T);
MakeShape(F, TF);
}
@ -455,6 +464,10 @@ void BRep_Builder::MakeFace(TopoDS_Face& F,
const Standard_Real Tol) const
{
Handle(BRep_TFace) TF = new BRep_TFace();
if(!F.IsNull() && F.Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::MakeFace");
}
TF->Surface(S);
TF->Tolerance(Tol);
TF->Location(L);
@ -473,6 +486,10 @@ void BRep_Builder::UpdateFace(const TopoDS_Face& F,
const Standard_Real Tol) const
{
const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &F.TShape());
if(TF->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateFace");
}
TF->Surface(S);
TF->Tolerance(Tol);
TF->Location(L.Predivided(F.Location()));
@ -488,7 +505,12 @@ void BRep_Builder::UpdateFace(const TopoDS_Face& F,
void BRep_Builder::UpdateFace(const TopoDS_Face& F,
const Handle(Poly_Triangulation)& T) const
{
(*((Handle(BRep_TFace)*) &F.TShape()))->Triangulation(T);
const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &F.TShape());
if(TF->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateFace");
}
TF->Triangulation(T);
F.TShape()->Modified(Standard_True);
}
@ -501,7 +523,12 @@ void BRep_Builder::UpdateFace(const TopoDS_Face& F,
void BRep_Builder::UpdateFace(const TopoDS_Face& F,
const Standard_Real Tol) const
{
(*((Handle(BRep_TFace)*) &F.TShape()))->Tolerance(Tol);
const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &F.TShape());
if(TF->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateFace");
}
TF->Tolerance(Tol);
F.TShape()->Modified(Standard_True);
}
@ -514,7 +541,12 @@ void BRep_Builder::UpdateFace(const TopoDS_Face& F,
void BRep_Builder::NaturalRestriction(const TopoDS_Face& F,
const Standard_Boolean N) const
{
(*((Handle(BRep_TFace)*) &F.TShape()))->NaturalRestriction(N);
const Handle(BRep_TFace)& TF = (*((Handle(BRep_TFace)*) &F.TShape()));
if(TF->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::NaturalRestriction");
}
TF->NaturalRestriction(N);
F.TShape()->Modified(Standard_True);
}
@ -527,6 +559,10 @@ void BRep_Builder::NaturalRestriction(const TopoDS_Face& F,
void BRep_Builder::MakeEdge(TopoDS_Edge& E) const
{
Handle(BRep_TEdge) TE = new BRep_TEdge();
if(!E.IsNull() && E.Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::MakeEdge");
}
TE->Closed(Standard_False);
MakeShape(E,TE);
}
@ -543,6 +579,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const Standard_Real Tol) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C,l);
@ -565,6 +605,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const Standard_Real Tol) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C,S,l);
@ -588,6 +632,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const gp_Pnt2d& Pl) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C,S,l,Pf,Pl);
@ -610,6 +658,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const Standard_Real Tol) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C1,C2,S,l);
@ -636,6 +688,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const gp_Pnt2d& Pl) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
UpdateCurves(TE->ChangeCurves(),C1,C2,S,l,Pf,Pl);
@ -657,7 +713,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location& L) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
@ -694,6 +753,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location& L) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
Standard_Boolean isModified = Standard_False;
@ -741,6 +804,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location& L) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
const TopLoc_Location l = L.Predivided(E.Location());
Standard_Boolean isModified = Standard_False;
@ -800,6 +867,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location& L) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
TopLoc_Location l = L.Predivided(E.Location());
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
@ -854,6 +925,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const TopLoc_Location& L) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
TopLoc_Location l = L.Predivided(E.Location());
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
@ -890,6 +965,10 @@ void BRep_Builder::UpdateEdge(const TopoDS_Edge& E,
const Standard_Real Tol) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateEdge");
}
TE->UpdateTolerance(Tol);
TE->Modified(Standard_True);
}
@ -924,7 +1003,10 @@ void BRep_Builder::Continuity(const TopoDS_Edge& E,
const GeomAbs_Shape C)const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::Continuity");
}
const TopLoc_Location l1 = L1.Predivided(E.Location());
const TopLoc_Location l2 = L2.Predivided(E.Location());
@ -942,6 +1024,10 @@ void BRep_Builder::SameParameter(const TopoDS_Edge& E,
const Standard_Boolean S) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::SameParameter");
}
TE->SameParameter(S);
TE->Modified(Standard_True);
}
@ -955,6 +1041,10 @@ void BRep_Builder::SameRange(const TopoDS_Edge& E,
const Standard_Boolean S) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::SameRange");
}
TE->SameRange(S);
TE->Modified(Standard_True);
}
@ -968,6 +1058,10 @@ void BRep_Builder::Degenerated(const TopoDS_Edge& E,
const Standard_Boolean D) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::Degenerated");
}
TE->Degenerated(D);
if (D) {
// set a null 3d curve
@ -989,7 +1083,10 @@ void BRep_Builder::Range(const TopoDS_Edge& E,
{
// set the range to all the representations if Only3d=FALSE
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::Range");
}
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
Handle(BRep_GCurve) GC;
@ -1032,6 +1129,10 @@ void BRep_Builder::Range(const TopoDS_Edge& E,
const Standard_Real Last) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::Range");
}
const TopLoc_Location l = L.Predivided(E.Location());
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
@ -1074,9 +1175,12 @@ void BRep_Builder::Transfert(const TopoDS_Edge& Ein,
const TopoDS_Edge& Eout) const
{
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Ein.TShape());
if(TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::Transfert");
}
const Standard_Real tol = TE->Tolerance();
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
@ -1123,7 +1227,10 @@ void BRep_Builder::UpdateVertex(const TopoDS_Vertex& V,
const Standard_Real Tol) const
{
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
if(TV->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateVertex");
}
TV->Pnt(P.Transformed(V.Location().Inverted().Transformation()));
TV->UpdateTolerance(Tol);
TV->Modified(Standard_True);
@ -1147,6 +1254,11 @@ void BRep_Builder::UpdateVertex(const TopoDS_Vertex& V,
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TV->Locked() || TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateVertex");
}
TopLoc_Location L = E.Location().Predivided(V.Location());
// Search the vertex in the edge
@ -1228,6 +1340,10 @@ void BRep_Builder::UpdateVertex(const TopoDS_Vertex& V,
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
if(TV->Locked() || TE->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateVertex");
}
// Search the vertex in the edge
TopAbs_Orientation ori = TopAbs_INTERNAL;
@ -1295,6 +1411,11 @@ void BRep_Builder::UpdateVertex(const TopoDS_Vertex& Ve,
{
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &Ve.TShape());
if(TV->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateVertex");
}
TopLoc_Location L;
const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
L = L.Predivided(Ve.Location());
@ -1314,6 +1435,12 @@ void BRep_Builder::UpdateVertex(const TopoDS_Vertex& V,
const Standard_Real Tol) const
{
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
if(TV->Locked())
{
TopoDS_LockedShape::Raise("BRep_Builder::UpdateVertex");
}
TV->UpdateTolerance(Tol);
TV->Modified(Standard_True);
}

View File

@ -34,6 +34,7 @@
#include <BRepTools_WireExplorer.hxx>
#include <BRepTools_ShapeSet.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_TEdge.hxx>
#include <Precision.hxx>
#include <Poly_Triangulation.hxx>
#include <gp_Ax2.hxx>
@ -968,6 +969,112 @@ static Standard_Integer countshapes(Draw_Interpretor& di,
return 0;
}
//=======================================================================
//
//=======================================================================
void setProp(TopoDS_Shape Sh, const char** a, Standard_Integer n)
{
Standard_Integer i;
for(i = 2; i < n; i++) {
if (strstr ( a[i], "free" )) {
if(a[i][0] == '-') {
Sh.Free(Standard_False);
}
else {
Sh.Free(Standard_True);
}
}
if (strstr ( a[i], "modified" )) {
if(a[i][0] == '-') {
Sh.Modified(Standard_False);
}
else {
Sh.Modified(Standard_True);
}
}
if (strstr ( a[i], "checked" )) {
if(a[i][0] == '-') {
Sh.Checked(Standard_False);
}
else {
Sh.Checked(Standard_True);
}
}
if (strstr ( a[i], "orientable" )) {
if(a[i][0] == '-') {
Sh.Orientable(Standard_False);
}
else {
Sh.Orientable(Standard_True);
}
}
if (strstr ( a[i], "closed" )) {
if(a[i][0] == '-') {
Sh.Closed(Standard_False);
}
else {
Sh.Closed(Standard_True);
}
}
if (strstr ( a[i], "infinite" )) {
if(a[i][0] == '-') {
Sh.Infinite(Standard_False);
}
else {
Sh.Infinite(Standard_True);
}
}
if (strstr ( a[i], "convex" )) {
if(a[i][0] == '-') {
Sh.Convex(Standard_False);
}
else {
Sh.Convex(Standard_True);
}
}
if (strstr ( a[i], "locked" )) {
if(a[i][0] == '-') {
Sh.Locked(Standard_False);
}
else {
Sh.Locked(Standard_True);
}
}
}
}
//=======================================================================
//
//=======================================================================
static Standard_Integer setFlags(Draw_Interpretor& ,
Standard_Integer n, const char** a)
{
if (n < 3) return 1;
TopExp_Explorer ex;
TopoDS_Shape Sh = DBRep::Get(a[1]);
if (Sh.IsNull()) return 1;
setProp(Sh, a, n);
for (ex.Init (Sh,TopAbs_VERTEX); ex.More(); ex.Next()) {
TopoDS_Shape S = ex.Current();
setProp(S, a, n);
}
for (ex.Init (Sh,TopAbs_EDGE); ex.More(); ex.Next()) {
TopoDS_Shape S = ex.Current();
setProp(S, a, n);
}
for (ex.Init (Sh,TopAbs_FACE); ex.More(); ex.Next()) {
TopoDS_Shape S = ex.Current();
setProp(S, a, n);
}
return 0;
}
//=======================================================================
//memory management
//=======================================================================
@ -1200,6 +1307,9 @@ void DBRep::BasicCommands(Draw_Interpretor& theCommands)
__FILE__,nbshapes,g);
theCommands.Add("numshapes","numshapes s; size of shape",__FILE__,numshapes,g);
theCommands.Add("countshapes","countshapes s; count of shape",__FILE__,countshapes,g);
theCommands.Add("setflags",
"setflags shape_name flag1[flag2...]\n sets flags for shape(free, modidfied, checked, orientable, closed, infinite, convex, locked), for exmple <setflags a free> or <setflags a -free> if necessary unflag ",
__FILE__,setFlags,g);
// theCommands.Add("dumpmmgt",
// "dump le contenu du gestionnaire de memoire",__FILE__,dumpmmgt,g);

View File

@ -35,6 +35,10 @@ is
exception FrozenShape inherits DomainError;
---Purpose: An attempt was made to modify a Shape already
-- shared or protected.
exception LockedShape inherits DomainError;
---Purpose: An attempt was made to modify a geometry of Shape already
-- shared or protected.
exception UnCompatibleShapes inherits DomainError;
---Purpose: An incorrect insertion was attempted.

View File

@ -131,6 +131,20 @@ is
raises NullObject from Standard
is static;
Locked(me) returns Boolean
---Purpose: Returns the locked flag.
--
---C++: inline
raises NullObject from Standard
is static;
Locked(me : in out; F : Boolean)
---Purpose: Sets the locked flag.
--
---C++: inline
raises NullObject from Standard
is static;
Modified(me) returns Boolean
---Purpose: Returns the modification flag.
--

View File

@ -152,6 +152,26 @@ inline void TopoDS_Shape::Free (const Standard_Boolean B)
myTShape->Free(B);
}
//=======================================================================
//function : Locked
//purpose :
//=======================================================================
inline Standard_Boolean TopoDS_Shape::Locked () const
{
return myTShape->Locked();
}
//=======================================================================
//function : Locked
//purpose :
//=======================================================================
inline void TopoDS_Shape::Locked (const Standard_Boolean B)
{
myTShape->Locked(B);
}
//=======================================================================
//function : Modified
//purpose :

View File

@ -72,6 +72,16 @@ is
---C++: inline
---Purpose: Sets the free flag.
is static;
Locked(me) returns Boolean
---C++: inline
---Purpose: Returns the locked flag.
is static;
Locked(me : mutable; F : Boolean)
---C++: inline
---Purpose: Sets the locked flag.
is static;
Modified(me) returns Boolean
---C++: inline

View File

@ -26,6 +26,7 @@
#define TopoDS_TShape_Flags_Closed (1<<4)
#define TopoDS_TShape_Flags_Infinite (1<<5)
#define TopoDS_TShape_Flags_Convex (1<<6)
#define TopoDS_TShape_Flags_Locked (1<<7)
//=======================================================================
@ -61,6 +62,26 @@ inline void TopoDS_TShape::Free(const Standard_Boolean F)
else myFlags &= ~TopoDS_TShape_Flags_Free;
}
//=======================================================================
//function : Locked
//purpose :
//=======================================================================
inline Standard_Boolean TopoDS_TShape::Locked() const
{
return ((myFlags & TopoDS_TShape_Flags_Locked) != 0);
}
//=======================================================================
//function : Locked
//purpose :
//=======================================================================
inline void TopoDS_TShape::Locked(const Standard_Boolean F)
{
if (F) myFlags |= TopoDS_TShape_Flags_Locked;
else myFlags &= ~TopoDS_TShape_Flags_Locked;
}
//=======================================================================
//function : Modified
//purpose :

View File

@ -0,0 +1,11 @@
puts "TODO #23876 ALL: Error : The bopcut cannot be built."
restore [locate_data_file case_9_edge.brep] a
restore [locate_data_file case_9_wire3.brep] b
settolerance a 0.1
setflags b locked
bop a b
bopcut result
set length 613.678
set nbsh_v 3
set nbsh_e 2