mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-07 18:30:55 +03:00
Extend the Offset operation (Join Type "Intersection", mode "Complete") to allow different offset values on adjacent co-planar faces. The gap between adjacent faces is closed by creating artificial face perpendicular to the face. Adding test cases.
364 lines
9.5 KiB
C++
364 lines
9.5 KiB
C++
// Created on: 1995-10-26
|
|
// Created by: Yves FRICAUD
|
|
// Copyright (c) 1995-1999 Matra Datavision
|
|
// 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 <BRepAlgo_Image.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_MapOfShape.hxx>
|
|
|
|
//=======================================================================
|
|
//function : BRepAlgo_Image
|
|
//purpose :
|
|
//=======================================================================
|
|
BRepAlgo_Image::BRepAlgo_Image()
|
|
{
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SetRoot
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::SetRoot(const TopoDS_Shape& S)
|
|
{
|
|
roots.Append(S);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Bind
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Bind(const TopoDS_Shape& OldS,
|
|
const TopoDS_Shape& NewS)
|
|
{
|
|
if (down.IsBound(OldS)) {
|
|
throw Standard_ConstructionError(" BRepAlgo_Image::Bind");
|
|
return;
|
|
}
|
|
TopTools_ListOfShape L;
|
|
down.Bind(OldS,L);
|
|
down(OldS).Append(NewS);
|
|
up.Bind(NewS,OldS);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Bind
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Bind(const TopoDS_Shape& OldS,
|
|
const TopTools_ListOfShape& L)
|
|
{
|
|
if (HasImage(OldS)) {
|
|
throw Standard_ConstructionError(" BRepAlgo_Image::Bind");
|
|
return;
|
|
}
|
|
TopTools_ListIteratorOfListOfShape it(L);
|
|
for (; it.More(); it.Next()) {
|
|
if (!HasImage(OldS))
|
|
Bind(OldS, it.Value());
|
|
else
|
|
Add (OldS, it.Value());
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Clear
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Clear()
|
|
{
|
|
roots.Clear();
|
|
up .Clear();
|
|
down .Clear();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Add
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Add(const TopoDS_Shape& OldS, const TopoDS_Shape& NewS)
|
|
{
|
|
if (!HasImage(OldS)) {
|
|
throw Standard_ConstructionError(" BRepAlgo_Image::Add");
|
|
}
|
|
down(OldS).Append(NewS);
|
|
up.Bind(NewS,OldS);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Add
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Add(const TopoDS_Shape& OldS,
|
|
const TopTools_ListOfShape& L)
|
|
{
|
|
TopTools_ListIteratorOfListOfShape it(L);
|
|
for (; it.More(); it.Next()) {
|
|
Add(OldS,it.Value());
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Remove
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Remove(const TopoDS_Shape& S)
|
|
{
|
|
if (!up.IsBound(S)) {
|
|
throw Standard_ConstructionError(" BRepAlgo_Image::Remove");
|
|
}
|
|
const TopoDS_Shape& OldS = up(S);
|
|
TopTools_ListOfShape& L = down(OldS);
|
|
TopTools_ListIteratorOfListOfShape it(L);
|
|
while (it.More()) {
|
|
if (it.Value().IsSame(S)) {
|
|
L.Remove(it);
|
|
break;
|
|
}
|
|
it.Next();
|
|
}
|
|
if (L.IsEmpty()) down.UnBind(OldS);
|
|
up.UnBind(S);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : TopTools_ListOfShape&
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TopTools_ListOfShape& BRepAlgo_Image::Roots() const
|
|
{
|
|
return roots;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsImage
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepAlgo_Image::IsImage(const TopoDS_Shape& S) const
|
|
{
|
|
return up.IsBound(S);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ImageFrom
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TopoDS_Shape& BRepAlgo_Image::ImageFrom(const TopoDS_Shape& S) const
|
|
{
|
|
if (!up.IsBound(S)) {
|
|
throw Standard_ConstructionError(" BRepAlgo_Image::ImageFrom");
|
|
}
|
|
return up(S);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FirstImageFrom
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TopoDS_Shape& BRepAlgo_Image::Root(const TopoDS_Shape& S)
|
|
const
|
|
{
|
|
if (!up.IsBound(S)) {
|
|
throw Standard_ConstructionError(" BRepAlgo_Image::FirstImageFrom");
|
|
}
|
|
|
|
TopoDS_Shape S1 = up(S);
|
|
TopoDS_Shape S2 = S;
|
|
|
|
if ( S1.IsSame(S2))
|
|
return up(S);
|
|
|
|
while ( up.IsBound(S1)) {
|
|
S2 = S1;
|
|
S1 = up(S1);
|
|
if ( S1.IsSame(S2)) break;
|
|
}
|
|
return up(S2);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : HasImage
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepAlgo_Image::HasImage(const TopoDS_Shape& S) const
|
|
{
|
|
return down.IsBound(S);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TopTools_ListOfShape&
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TopTools_ListOfShape& BRepAlgo_Image::Image(const TopoDS_Shape& S) const
|
|
{
|
|
if (!HasImage(S)) {
|
|
static TopTools_ListOfShape L;
|
|
L.Append(S);
|
|
return L;
|
|
}
|
|
return down(S);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : TopTools_ListOfShape&
|
|
//purpose :
|
|
//=======================================================================
|
|
void BRepAlgo_Image::LastImage(const TopoDS_Shape& S,
|
|
TopTools_ListOfShape& L) const
|
|
{
|
|
if (!down.IsBound(S)) {
|
|
L.Append(S);
|
|
}
|
|
else {
|
|
TopTools_ListIteratorOfListOfShape it(down(S));
|
|
for (; it.More(); it.Next()) {
|
|
if (it.Value().IsSame(S)) {
|
|
L.Append(S);
|
|
}
|
|
else {
|
|
LastImage(it.Value(),L);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Compact
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Compact()
|
|
{
|
|
TopTools_DataMapOfShapeListOfShape M;
|
|
TopTools_ListIteratorOfListOfShape it(roots);
|
|
for (; it.More(); it.Next()) {
|
|
const TopoDS_Shape& S = it.Value();
|
|
TopTools_ListOfShape LI;
|
|
if (HasImage(S)) LastImage(S,LI);
|
|
M.Bind (S,LI);
|
|
}
|
|
up.Clear();
|
|
down.Clear();
|
|
for (it.Initialize(roots); it.More(); it.Next()) {
|
|
if (M.IsBound(it.Value())) {
|
|
Bind(it.Value(), M(it.Value()));
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Filter
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepAlgo_Image::Filter(const TopoDS_Shape& S,
|
|
const TopAbs_ShapeEnum T)
|
|
|
|
{
|
|
TopExp_Explorer exp(S,T) ;
|
|
TopTools_MapOfShape M;
|
|
for (; exp.More(); exp.Next()) {M.Add(exp.Current());}
|
|
Standard_Boolean Change = Standard_True;
|
|
while (Change) {
|
|
Change = Standard_False;
|
|
TopTools_DataMapIteratorOfDataMapOfShapeShape mit(up);
|
|
for (; mit.More(); mit.Next()) {
|
|
const TopoDS_Shape& aS = mit.Key();
|
|
if (aS.ShapeType() == T && !M.Contains(aS)) {
|
|
Remove(aS);
|
|
Change = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : RemoveRoot
|
|
//purpose :
|
|
//=======================================================================
|
|
void BRepAlgo_Image::RemoveRoot (const TopoDS_Shape& Root)
|
|
{
|
|
Standard_Boolean isRemoved = Standard_False;
|
|
for (TopTools_ListOfShape::Iterator it (roots); it.More(); it.Next())
|
|
{
|
|
if (Root.IsSame (it.Value()))
|
|
{
|
|
roots.Remove (it);
|
|
isRemoved = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isRemoved)
|
|
return;
|
|
|
|
const TopTools_ListOfShape* pNewS = down.Seek (Root);
|
|
if (pNewS)
|
|
{
|
|
for (TopTools_ListOfShape::Iterator it (*pNewS); it.More(); it.Next())
|
|
{
|
|
const TopoDS_Shape *pOldS = up.Seek (it.Value());
|
|
if (pOldS && pOldS->IsSame (Root))
|
|
up.UnBind (it.Value());
|
|
}
|
|
down.UnBind (Root);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ReplaceRoot
|
|
//purpose :
|
|
//=======================================================================
|
|
void BRepAlgo_Image::ReplaceRoot (const TopoDS_Shape& OldRoot,
|
|
const TopoDS_Shape& NewRoot)
|
|
{
|
|
if (!HasImage (OldRoot))
|
|
return;
|
|
|
|
const TopTools_ListOfShape& aLImage = Image (OldRoot);
|
|
if (HasImage (NewRoot))
|
|
Add (NewRoot, aLImage);
|
|
else
|
|
Bind (NewRoot, aLImage);
|
|
|
|
SetRoot (NewRoot);
|
|
RemoveRoot (OldRoot);
|
|
}
|