Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// 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_ShapeMapHasher.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Map.hxx>
//=================================================================================================
BRepAlgo_Image::BRepAlgo_Image() = default;
//=================================================================================================
void BRepAlgo_Image::SetRoot(const TopoDS_Shape& S)
{
roots.Append(S);
}
//=================================================================================================
void BRepAlgo_Image::Bind(const TopoDS_Shape& OldS, const TopoDS_Shape& NewS)
{
if (down.IsBound(OldS))
{
throw Standard_ConstructionError(" BRepAlgo_Image::Bind");
return;
}
NCollection_List<TopoDS_Shape> L;
down.Bind(OldS, L);
down(OldS).Append(NewS);
up.Bind(NewS, OldS);
}
//=================================================================================================
void BRepAlgo_Image::Bind(const TopoDS_Shape& OldS, const NCollection_List<TopoDS_Shape>& L)
{
if (HasImage(OldS))
{
throw Standard_ConstructionError(" BRepAlgo_Image::Bind");
return;
}
NCollection_List<TopoDS_Shape>::Iterator it(L);
for (; it.More(); it.Next())
{
if (!HasImage(OldS))
{
Bind(OldS, it.Value());
}
else
{
Add(OldS, it.Value());
}
}
}
//=================================================================================================
void BRepAlgo_Image::Clear()
{
roots.Clear();
up.Clear();
down.Clear();
}
//=================================================================================================
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);
}
//=================================================================================================
void BRepAlgo_Image::Add(const TopoDS_Shape& OldS, const NCollection_List<TopoDS_Shape>& L)
{
NCollection_List<TopoDS_Shape>::Iterator it(L);
for (; it.More(); it.Next())
{
Add(OldS, it.Value());
}
}
//=================================================================================================
void BRepAlgo_Image::Remove(const TopoDS_Shape& S)
{
if (!up.IsBound(S))
{
throw Standard_ConstructionError(" BRepAlgo_Image::Remove");
}
const TopoDS_Shape& OldS = up(S);
NCollection_List<TopoDS_Shape>& L = down(OldS);
NCollection_List<TopoDS_Shape>::Iterator 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 : NCollection_List<TopoDS_Shape>&
// purpose :
//=======================================================================
const NCollection_List<TopoDS_Shape>& BRepAlgo_Image::Roots() const
{
return roots;
}
//=================================================================================================
bool BRepAlgo_Image::IsImage(const TopoDS_Shape& S) const
{
return up.IsBound(S);
}
//=================================================================================================
const TopoDS_Shape& BRepAlgo_Image::ImageFrom(const TopoDS_Shape& S) const
{
if (!up.IsBound(S))
{
throw Standard_ConstructionError(" BRepAlgo_Image::ImageFrom");
}
return up(S);
}
//=================================================================================================
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);
}
//=================================================================================================
bool BRepAlgo_Image::HasImage(const TopoDS_Shape& S) const
{
return down.IsBound(S);
}
//=======================================================================
// function : NCollection_List<TopoDS_Shape>&
// purpose :
//=======================================================================
const NCollection_List<TopoDS_Shape>& BRepAlgo_Image::Image(const TopoDS_Shape& S) const
{
if (!HasImage(S))
{
static NCollection_List<TopoDS_Shape> L;
L.Append(S);
return L;
}
return down(S);
}
//=======================================================================
// function : NCollection_List<TopoDS_Shape>&
// purpose :
//=======================================================================
void BRepAlgo_Image::LastImage(const TopoDS_Shape& S, NCollection_List<TopoDS_Shape>& L) const
{
if (!down.IsBound(S))
{
L.Append(S);
}
else
{
NCollection_List<TopoDS_Shape>::Iterator it(down(S));
for (; it.More(); it.Next())
{
if (it.Value().IsSame(S))
{
L.Append(S);
}
else
{
LastImage(it.Value(), L);
}
}
}
}
//=================================================================================================
void BRepAlgo_Image::Compact()
{
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher> M;
NCollection_List<TopoDS_Shape>::Iterator it(roots);
for (; it.More(); it.Next())
{
const TopoDS_Shape& S = it.Value();
NCollection_List<TopoDS_Shape> 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()));
}
}
}
//=================================================================================================
void BRepAlgo_Image::Filter(const TopoDS_Shape& S, const TopAbs_ShapeEnum T)
{
TopExp_Explorer exp(S, T);
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> M;
for (; exp.More(); exp.Next())
{
M.Add(exp.Current());
}
bool Change = true;
while (Change)
{
Change = false;
NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher>::Iterator mit(up);
for (; mit.More(); mit.Next())
{
const TopoDS_Shape& aS = mit.Key();
if (aS.ShapeType() == T && !M.Contains(aS))
{
Remove(aS);
Change = true;
break;
}
}
}
}
//=================================================================================================
void BRepAlgo_Image::RemoveRoot(const TopoDS_Shape& Root)
{
bool isRemoved = false;
for (NCollection_List<TopoDS_Shape>::Iterator it(roots); it.More(); it.Next())
{
if (Root.IsSame(it.Value()))
{
roots.Remove(it);
isRemoved = true;
break;
}
}
if (!isRemoved)
{
return;
}
const NCollection_List<TopoDS_Shape>* pNewS = down.Seek(Root);
if (pNewS)
{
for (NCollection_List<TopoDS_Shape>::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);
}
}
//=================================================================================================
void BRepAlgo_Image::ReplaceRoot(const TopoDS_Shape& OldRoot, const TopoDS_Shape& NewRoot)
{
if (!HasImage(OldRoot))
{
return;
}
const NCollection_List<TopoDS_Shape>& aLImage = Image(OldRoot);
if (HasImage(NewRoot))
{
Add(NewRoot, aLImage);
}
else
{
Bind(NewRoot, aLImage);
}
SetRoot(NewRoot);
RemoveRoot(OldRoot);
}