zoukankan      html  css  js  c++  java
  • BRep Builder

    BRep Builder

    eryar@163.com

    1 Introduction

    BRep_Builder提供了创建、修改BRep模型的方法。使用这个类,你可以从底层自己构建BRep体,前提条件是你要对BRep模型的数据结构有一定理解。边界表示法BRep的重点在边界的定义,打开BRep_Builder的类图:

     

    可以看到其中重载了很多UpdateEdge函数,每个UpdateEdge函数都修改了Edge中的几何数据,包括边界的定义数据。若能理解每个UpdateEdge函数,则对OpenCASCADEBREP数据结构就能理解了。本文主要介绍其中两个函数的用法:AddRemove

     2 Add Shape

    BRep_BuilderAdd函数的字面意思是将一个Shape添加到另外一个Shape中。因这个函数的实现比较简单,把源码列出如下:

    void TopoDS_Builder::Add (TopoDS_Shape& aShape, 
                              const TopoDS_Shape& aComponent) const
    {
      // From now the Component cannot be edited
      aComponent.TShape()->Free(Standard_False);
    
      // Note that freezing aComponent before testing if aShape is free
      // prevents from self-insertion
      // but aShape will be frozen when the Exception is raised
      if (aShape.Free())
      {
        static const unsigned int aTb[9]=
        {
          //COMPOUND to:
          (1<<((unsigned int)TopAbs_COMPOUND)),
          //COMPSOLID to:
          (1<<((unsigned int)TopAbs_COMPOUND)),
          //SOLID to:
          (1<<((unsigned int)TopAbs_COMPOUND)) |
          (1<<((unsigned int)TopAbs_COMPSOLID)),
          //SHELL to:
          (1<<((unsigned int)TopAbs_COMPOUND)) |
          (1<<((unsigned int)TopAbs_SOLID)),
          //FACE to:
          (1<<((unsigned int)TopAbs_COMPOUND)) |
          (1<<((unsigned int)TopAbs_SHELL)),
          //WIRE to:
          (1<<((unsigned int)TopAbs_COMPOUND)) |
          (1<<((unsigned int)TopAbs_FACE)),
          //EDGE to:
          (1<<((unsigned int)TopAbs_COMPOUND)) |
          (1<<((unsigned int)TopAbs_SOLID)) |
          (1<<((unsigned int)TopAbs_WIRE)),
          //VERTEX to:
          (1<<((unsigned int)TopAbs_COMPOUND)) |
          (1<<((unsigned int)TopAbs_SOLID)) |
          (1<<((unsigned int)TopAbs_FACE)) |
          (1<<((unsigned int)TopAbs_EDGE)),
          //SHAPE to:
          0
        };
        //
        const unsigned int iC=(unsigned int)aComponent.ShapeType();
        const unsigned int iS=(unsigned int)aShape.ShapeType();
        //
        if ((aTb[iC] & (1<<iS)) != 0) {
          TopoDS_ListOfShape& L = aShape.TShape()->myShapes;
          L.Append(aComponent);
          TopoDS_Shape& S = L.Last();
          //
          // compute the relative Orientation
          if (aShape.Orientation() == TopAbs_REVERSED)
            S.Reverse();
          //
          // and the Relative Location
          const TopLoc_Location& aLoc=aShape.Location();
          if (!aLoc.IsIdentity())
            S.Move(aLoc.Inverted());
          //
          // Set the TShape as modified.
          aShape.TShape()->Modified(Standard_True);
        }
        else {
          throw TopoDS_UnCompatibleShapes("TopoDS_Builder::Add");
        }
      }
      else {
        throw TopoDS_FrozenShape("TopoDS_Buider::Add");
      }
    }

    Add函数通过一个静态的检查列表,来检查添加的Shape是不是合法的,即FACE只能添加到SHELLCOMPOUND中,EDGE只能添加到WIRESOLIDCOMPOUND中等。添加之后还检查了ShapeORIENTATION及位置信息并作相应调整。不满足条件的情况都会抛出异常,所以对于Add函数需要增加异常处理逻辑。

    使用这个函数需要注意的是这个Add只是简单的将Shape添加到TShapeShape表中,并没有维护BREP的边界信息。

    3 Remove Shape

    Add对应的有Remove函数,可以从一个Shape中删除一个子Shape。还是打开源码,有源码有真相:

    //=======================================================================
    //function : Remove
    //purpose  : Remove a Shape from an other one
    //=======================================================================
    
    void TopoDS_Builder::Remove (TopoDS_Shape& aShape, 
                                 const TopoDS_Shape& aComponent) const
    {
      // check  if aShape  is  not Frozen
      TopoDS_FrozenShape_Raise_if (!aShape.Free(),"TopoDS_Builder::Remove");
      
      // compute the relative Orientation and Location of aComponent
      TopoDS_Shape S = aComponent;
      if (aShape.Orientation() == TopAbs_REVERSED)
        S.Reverse();
      S.Location(S.Location().Predivided(aShape.Location()));
    
      TopoDS_ListOfShape& L = aShape.TShape()->myShapes;
      TopoDS_ListIteratorOfListOfShape It(L);
      while (It.More()) {
        if (It.Value() == S) {
          L.Remove(It);
          aShape.TShape()->Modified(Standard_True);
          break;
        }
        It.Next();
      }
    }

    从源码中可知,Remove实现的逻辑也是很简单的:

    检查Shape是不是Free的,若不是则抛出异常;

    计算要删除ComponentORIENTATIONLOCATION

    Shape列中查找Component,若找到将其从列表中删除;

    删除操作比添加操作要简单,一个是把已有的数据删除,一个是从无到有的构建数据。从函数实现代码来看,删除操作也是简单的从Shape列表中删除指定的Shape。删除之后多余的边界信息还会存在原来的Shape中,要确保删除的Shape之后没有多余信息,还需要删除没有使用的PCurves

     

    上图所示为删除一个底面的圆柱体。

     4 Conclusion

    BRep_Builder的操作需要以充分理解OpenCASCADEBREP数据结构为前提,因为其AddRemove函数并没有提供维护边界的功能,只是将指定的Shape添加到列表中或从列表中删除。

  • 相关阅读:
    https证书设置以及设置301跳转
    SVN服务器从windows迁移至Linux
    禅道从windows迁移到linux
    gitlab安装和迁移
    java 枚举类型enum 的使用
    java中的日期注意事项
    C# using 三种使用方式 zhuan
    设计路径测试覆盖率与代码测试覆盖率
    Selenium API (C#) 转
    Selenium 2.0 WebDriver with Visual Studio, C#, & IE
  • 原文地址:https://www.cnblogs.com/opencascade/p/BRep_Builder.html
Copyright © 2011-2022 走看看