OCCT中的偏移面 (Geom_OffsetSurface)

 三维空间中,偏移面的定义如下:

  •  基础面(偏移面与基础面平行)。
  •  偏移面与基础面的距离。

    通过将基础面上的点沿其法向移动特定距离得到偏移面上的点。法向通过叉积D1u ^ D1v 得到,D1u和D1v分别是在参数u和v方向上与基础面相切的向量。偏移值的符号决定了相对于基础面的哪个侧面做偏移。如果偏移为正,则沿法向做偏移,如果偏移为负,则沿法向的反向做偏移。如果isNotCheckC0 = TRUE,则尚未检查基础表面是否具有C0连续性。

  •  偏移表面是在基础面的一份拷贝上做偏移,因此,当基础面改变时,偏移平面不变。
  •  基础表面上的任何点都必须只定义一个法向量。这必须由用户验证,因为在构造时不进行检查以检测具有多个可能的法线方向的点。

    在OCCT中,偏移面的构造如下:

Geom_OffsetSurface::Geom_OffsetSurface (const Handle(Geom_Surface)& theSurf, 
                    const Standard_Real theOffset,
                    const Standard_Boolean isTheNotCheckC0) 
                    : offsetValue (theOffset) 
{

    SetBasisSurface(theSurf, isTheNotCheckC0);

}
void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S,
  const Standard_Boolean isNotCheckC0)
{
  Standard_Real aUf, aUl, aVf, aVl;
  S->Bounds(aUf, aUl, aVf, aVl);

  Handle(Surface) aCheckingSurf = Handle(Surface)::DownCast(S->Copy());
  Standard_Boolean isTrimmed = Standard_False;

  while(aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
    aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
  {
    if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
    {
      Handle(Geom_RectangularTrimmedSurface) aTrimS = 
        Handle(Geom_RectangularTrimmedSurface)::DownCast(aCheckingSurf);
      aCheckingSurf = aTrimS->BasisSurface();
      isTrimmed = Standard_True;
    }

    if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
    {
      Handle(Geom_OffsetSurface) aOS = 
        Handle(Geom_OffsetSurface)::DownCast(aCheckingSurf);
      aCheckingSurf = aOS->BasisSurface();
      offsetValue += aOS->Offset();
    }
  }


  myBasisSurfContinuity = aCheckingSurf->Continuity();

  Standard_Boolean isC0 = !isNotCheckC0 &&
    (myBasisSurfContinuity == GeomAbs_C0);

  // Basis surface must be at least C1
  if (isC0)
  {
    Handle(Geom_Curve) aCurve;

    if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
    {
      Handle(Geom_SurfaceOfRevolution) aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aCheckingSurf);
      aCurve = aRevSurf->BasisCurve();
    }
    else if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))
    {
      Handle(Geom_SurfaceOfLinearExtrusion) aLESurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aCheckingSurf);
      aCurve = aLESurf->BasisCurve();
    }

    if(!aCurve.IsNull())
    {
      while(aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
        aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
      {
        if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
        {
          Handle(Geom_TrimmedCurve) aTrimC = 
            Handle(Geom_TrimmedCurve)::DownCast(aCurve);
          aCurve = aTrimC->BasisCurve();
        }

        if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
        {
          Handle(Geom_OffsetCurve) aOC = 
            Handle(Geom_OffsetCurve)::DownCast(aCurve);
          aCurve = aOC->BasisCurve();
        }
      }
    }

    Standard_Real aUIsoPar = (aUf + aUl)/2.0, aVIsoPar = (aVf + aVl)/2.0;
    Standard_Boolean isUG1 = Standard_False, isVG1 = Standard_False;
 
    const Handle(Geom_Curve) aCurv1 = aCurve.IsNull() ? aCheckingSurf->UIso(aUIsoPar) : aCurve;
    const Handle(Geom_Curve) aCurv2 = aCheckingSurf->VIso(aVIsoPar);
    isUG1 = !aCurv1->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
    isVG1 = !aCurv2->IsKind(STANDARD_TYPE(Geom_BSplineCurve));

    if(!isUG1)
    {
      Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv1);
      isUG1 = aBC->IsG1(aVf, aVl, MyAngularToleranceForG1);
    }
    //
    if(!isVG1)
    {
      Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv2);
      isVG1 = aBC->IsG1(aUf, aUl, MyAngularToleranceForG1);
    }
    //
    if(isUG1 && isVG1) 
    {
      myBasisSurfContinuity = GeomAbs_G1;
      isC0 = Standard_False;
    }

    // Raise exception if still C0
    if (isC0)
      Standard_ConstructionError::Raise("Offset with no C1 Surface");
  }

  if(isTrimmed)
  {
    basisSurf = 
      new Geom_RectangularTrimmedSurface(aCheckingSurf, aUf, aUl, aVf, aVl);
  }
  else
  {
    basisSurf = aCheckingSurf;
  }
  
  equivSurf = Surface();
  //
  // Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
  // et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso 
  // et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour
  // detecter si une iso est degeneree.
  Standard_Real Tol = Precision::Confusion(); //0.0001;
  myOscSurf.Init(basisSurf,Tol);

}

  

你可能感兴趣的:(IFC)