Open CASCADE学习|TCL命令转化为C++(上)

目录

1、polyline rectangle1 d -R 0  R -R 0 -d R 0 -R R 0  d -R 0

2、circle circle1 0 0 0 0 0 1 R

3、mkedge circle1 circle1

4、wire circle1 circle1

5、plane p0

6、mkface rectangle1 p0 rectangle1

7、bcommon sec rectangle1 circle1

8、fuse sec sec circle2

9、cylinder cc 0 0 0 0 0 1 0 -4 0 4

10、line ll 0 0 a 80

11、trim ll ll 0 sqrt(a*a+H*H)

12、vertex v1 0 -R 0

13、trotate v2 0 0 0 0 0 1 180.*a/pi

14、mksweep sp

15、setsweep -G gg 0 0

16、addsweep lip

17、buildsweep spiral -S


这里取自麻花钻造型的例子

# Sample: creation of simple twist drill bit
​
#Category: Modeling
​
#Title: Drill
​
pload MODELING VISUALIZATION
​
# drill parameters (some terms taken from http://www.drill-bits.cn/drill-bits-quality.asp)
​
dset R  4.    ;# outer radius
​
dset D  2*R   ;# diameter
​
dset Rr 3.5   ;# chisel radius (outer radius minus body clearance)
​
dset b  1.    ;# web thickness (approximate)
​
dset d  b/2
​
dset H  80.   ;# height of the spiral part
​
dset a  3.*pi ;# total angle of spiral rotation
​
dset sigma 118 ;# point angle, in degrees
​
# Create section profile by sequence of Boolean operations
​
# on simple planar objects
​
puts "Creating the drill section profile..."
​
polyline rectangle1 d -R 0  R -R 0 -d R 0 -R R 0  d -R 0
​
circle circle1 0 0 0 0 0 1 R
​
mkedge circle1 circle1
​
wire circle1 circle1
​
circle circle2 0 0 0 0 0 1 Rr
​
mkedge circle2 circle2
​
wire circle2 circle2
​
plane p0
​
mkface rectangle1 p0 rectangle1
​
mkface circle1 p0 circle1
​
mkface circle2 p0 circle2
​
bcommon sec rectangle1 circle1
​
# note use of 'fuse' instead of 'bfuse' -- we need to get single face
​
fuse sec sec circle2
​
# Construct flute profile so as to have cutting lip straight after sharpening.
​
# Here we need to take into account spiral shift of the flute edge
​
# along the point length -- the way to do that is to make spiral
​
# from the desired cutting lip edge and then intersect it by plane
​
polyline lip d -d/2 0  d -R -R/tan(sigma/2*pi/180)
​
polyline sp 0 0 0 0 0 H
​
cylinder cc 0 0 0 0 0 1 0 -4 0 4
​
line ll 0 0 a 80
​
trim ll ll 0 sqrt(a*a+H*H)
​
vertex v1 0 -R 0
​
vertex v2 0 -R H
​
trotate v2 0 0 0 0 0 1 180.*a/pi
​
mkedge ee ll cc v1 v2
​
wire gg ee
​
mksweep sp
​
setsweep -G gg 0 0
​
addsweep lip
​
buildsweep spiral -S
​
mkface f0 p0 -R R -R R
​
bsection sflute spiral f0
​
# here we rely on that section curve is parameterized from 0 to 1 
​
# and directed as cutting lip edge;
​
# note that this can change if intersection algorithm is modified
​
explode sflute e
​
mkcurve cflute sflute_1
​
cvalue cflute 0. x0 y0 z0
​
cvalue cflute 1. x1 y1 z1
​
vertex vf0 x0 y0 z0 
​
vertex vf1 x1 y1 z1
​
# -- variant: replace curve by arc with start at x0,y0,z0 and end at x1,y1,z1,
​
# -- such that tanget at start point is along Y
​
#dset Rflute ((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0))/(2*(x1-x0))
​
#circle aflute x0+Rflute y0 0  0 0 1  Rflute
​
#mkedge sflute_1 aflute vf0 vf1
​
# make rounding in the flute; use circle with radius Rr/2
​
circle cround x0+Rr/2 y0 0 0 0 1 Rr/2
​
vertex vf3 x0+Rr y0 0
​
mkedge sflute_2 cround vf3 vf0
​
vertex vf2 R -R 0
​
edge sflute_3 vf3 vf2
​
edge sflute_4 vf2 vf1
​
wire w2 sflute_1 sflute_2 sflute_3 sflute_4
​
mkface flute p0 w2
​
# cut flute from profile
​
bcut sec sec flute
​
trotate flute 0 0 0 0 0 1 180.
​
bcut sec sec flute
​
donly sec
​
# sweep profile to get a drill body
​
puts "Sweeping the profile..."
​
mksweep sp
​
setsweep -G gg 0 0
​
explode sec w
​
addsweep sec_1
​
buildsweep base -S
​
# sharpen the drill (see http://tool-land.ru/zatochka-sverla.php)
​
puts "Sharpening..."
​
dset theta a*R/H*sin((90-sigma/2)*pi/180)
​
plane ax1 d 1.9*D "H+1.9*D/tan(pi/180.*sigma/2.)" 0 -1 -1
​
pcone sh1 ax1 0 100*sin((sigma-90)/2*pi/180.) 100
​
trotate sh1 0 0 0 0 0 1 -theta*180/pi
​
tcopy sh1 sh2
​
trotate sh2 0 0 0 0 0 1 180
​
box sh -D/2 -D/2 72 D D 20
​
bcommon qq sh1 sh2
​
bcut sharpener sh qq
​
bcut body base sharpener
​
# make a shank
​
puts "Making a shank..."
​
plane pl2 0 0 -40 0 0 1
​
pcylinder shank pl2 4 40
​
pcone transit R 0 R
​
plane pl3 0 0 -40 0 0 -0.5
​
pcone tail pl3 R 0 0.5
​
bfuse shank shank tail
​
bfuse shank shank transit
​
bfuse drill body shank
# check result
​
checkshape drill
​
# show result
​
puts "Displaying result..."
​
incmesh drill 0.01
​
vdisplay drill
​
vsetdispmode drill 1
​
vrenderparams -msaa 8
​
vfit
​
# show section and sweep path
​
ttranslate sec_1 0 0 H; trotate sec_1 0 0 0 0 0 1 a*180/pi; incmesh gg 0.01; vdisplay gg sec_1
​

下面是具体转化过程

1、polyline rectangle1 d -R 0  R -R 0 -d R 0 -R R 0  d -R 0

该命令的实现代码为:
 

static Standard_Integer polyline(Draw_Interpretor& , Standard_Integer n, const char** a)
{
  if (n < 8) return 1;
  if (((n-2) % 3) != 0) return 1;
  Standard_Integer i, j, np = (n-2) / 3;
  BRepBuilderAPI_MakePolygon W;
  j = 2;
  for (i = 1; i <= np; i ++) {
    W.Add(gp_Pnt(Draw::Atof(a[j]),Draw::Atof(a[j+1]),Draw::Atof(a[j+2])));
    j += 3;
  }
  DBRep::Set(a[1],W.Wire());
  return 0;
}

转化为C++代码:

BRepBuilderAPI_MakePolygon rectangle1;rectangle1.Add(gp_Pnt(d, -R, 0));rectangle1.Add(gp_Pnt(R, -R, 0));rectangle1.Add(gp_Pnt(-d, R, 0));rectangle1.Add(gp_Pnt(-R, R, 0));rectangle1.Add(gp_Pnt(d, -R, 0));

2、circle circle1 0 0 0 0 0 1 R

该命令的实现代码为:

else if (!strcmp(a[0],"circle")) {
    if (n == 5)
      result2d = 
  new Geom2d_Circle(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
           gp_Dir2d(1,0)),
        Draw::Atof(a[4]));
    else if (n == 6)
      result = 
  new Geom_Circle(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
             gp_Dir(0,0,1)),
      Draw::Atof(a[5]));
    else if (n == 7)
      result2d =
  new Geom2d_Circle(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
           gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5]))),
        Draw::Atof(a[6]));
    else if (n == 9)
      result = 
  new Geom_Circle(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
             gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7]))),
      Draw::Atof(a[8]));
    else if (n == 12)
      result = 
  new Geom_Circle(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
             gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
             gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10]))),
      Draw::Atof(a[11]));
    else
      return 1;
  }

转化为C++代码:

Handle(Geom_Circle) circle1 = new Geom_Circle(gp_Ax2(gp_Pnt(0, 0,0), gp_Dir(0,0, 1)), R);

3、mkedge circle1 circle1

该命令的实现代码为:
 

static Standard_Integer mkedge(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
  if (n < 3) return 1;
​
  Handle(Geom_Curve)   C   = DrawTrSurf::GetCurve(a[2]);
  Handle(Geom2d_Curve) C2d = DrawTrSurf::GetCurve2d(a[2]);
  if (C.IsNull() && C2d.IsNull()) {
    //std::cout << a[2] << " is not a curve" << std::endl;
    di << a[2] << " is not a curve\n";
    return 1;
  }
​
  TopoDS_Edge edge;
​
  if (n == 3) {
    if (!C.IsNull())   edge = BRepBuilderAPI_MakeEdge(C);
    else               edge = BRepBuilderAPI_MakeEdge2d(C2d);
  }
  else {
    Handle(Geom_Surface) S;
    Standard_Integer i = 0;
    if (!C2d.IsNull()) {
      S = DrawTrSurf::GetSurface(a[3]);
      if (!S.IsNull()) i = 1;
    }
    TopoDS_Shape aLocalShape(DBRep::Get(a[3+i],TopAbs_VERTEX));
    TopoDS_Vertex V1 = TopoDS::Vertex(aLocalShape);
//    TopoDS_Vertex V1 = TopoDS::Vertex(DBRep::Get(a[3+i],TopAbs_VERTEX));
    if (n == 5+i) {
      if (V1.IsNull()) {
        if (!C.IsNull())   
          edge = BRepBuilderAPI_MakeEdge(C,Draw::Atof(a[3]),Draw::Atof(a[4]));
        else if (S.IsNull())              
          edge = BRepBuilderAPI_MakeEdge2d(C2d,Draw::Atof(a[3]),Draw::Atof(a[4]));
        else
          edge = BRepBuilderAPI_MakeEdge(C2d,S,Draw::Atof(a[4]),Draw::Atof(a[5]));
      }
      else {
        aLocalShape = DBRep::Get(a[4+i],TopAbs_VERTEX);
        TopoDS_Vertex V2 = TopoDS::Vertex(aLocalShape);
//  TopoDS_Vertex V2 = TopoDS::Vertex(DBRep::Get(a[4+i],TopAbs_VERTEX));
        if (!C.IsNull())   
          edge = BRepBuilderAPI_MakeEdge(C,V1,V2);
        else if (S.IsNull())              
          edge = BRepBuilderAPI_MakeEdge2d(C2d,V1,V2);
        else
          edge = BRepBuilderAPI_MakeEdge(C2d,S,V1,V2);
      }
    }  
    else if (n == 7+i) {
      aLocalShape = DBRep::Get(a[5+i],TopAbs_VERTEX);
      TopoDS_Vertex V2 = TopoDS::Vertex(aLocalShape);
//      TopoDS_Vertex V2 = TopoDS::Vertex(DBRep::Get(a[5+i],TopAbs_VERTEX));
      if (!C.IsNull())   
        edge = BRepBuilderAPI_MakeEdge(C,V1,V2,Draw::Atof(a[4]),Draw::Atof(a[6]));
      else if (S.IsNull())         
        edge = BRepBuilderAPI_MakeEdge2d(C2d,V1,V2,Draw::Atof(a[4]),Draw::Atof(a[6]));
      else              
        edge = BRepBuilderAPI_MakeEdge(C2d,S,V1,V2,Draw::Atof(a[5]),Draw::Atof(a[7]));
    }
    else
      return 1;
  }
​
  DBRep::Set(a[1],edge);
  return 0;
}

转化为C++代码:

TopoDS_Edge circle1e = BRepBuilderAPI_MakeEdge(circle1);

4、wire circle1 circle1

该命令的实现代码为:

static Standard_Integer wire(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
  if (n < 3) return 1;
  Standard_Integer i;
  BRepBuilderAPI_MakeWire MW;
  Standard_Boolean IsUnsorted = !strcmp(a[2], "-unsorted");
​
  if (!IsUnsorted)
    for (i = 2; i < n; i ++) {
      TopoDS_Shape S = DBRep::Get(a[i]);
      if (S.IsNull()) continue;
      if (S.ShapeType() == TopAbs_EDGE)
        MW.Add(TopoDS::Edge(S));
      else if (S.ShapeType() == TopAbs_WIRE)
        MW.Add(TopoDS::Wire(S));
      else
        continue;
    }
  else
  {
    TopTools_ListOfShape aLE;
    for (i = 3; i < n; i ++) 
    {
      TopoDS_Shape S = DBRep::Get(a[i]);
      TopExp_Explorer Exp(S, TopAbs_EDGE);
      for (;Exp.More();Exp.Next())
      {
        const TopoDS_Edge& anE = TopoDS::Edge(Exp.Current()); 
        if (!anE.IsNull())
          aLE.Append(anE);
      }
    }
    MW.Add(aLE);
  }
​
  if (!MW.IsDone()) {
    //std::cout << "Wire not done" << std::endl;
    di << "Wire not done with an error:\n";
    switch (MW.Error()) 
    {
    case BRepBuilderAPI_EmptyWire:
      di << "BRepBuilderAPI_EmptyWire\n";
      break;
    case BRepBuilderAPI_DisconnectedWire:
      di << "BRepBuilderAPI_DisconnectedWire\n";
      break;
    case BRepBuilderAPI_NonManifoldWire:
      di << "BRepBuilderAPI_NonManifoldWire\n";
      break;
    default:
      break;
    }
  }
  else   
    DBRep::Set(a[1],MW);
  return 0;
}

转化为C++代码:

BRepBuilderAPI_MakeWire circle1w;circle1w.Add(circle1e);

5、plane p0

该命令的实现代码为:

static Standard_Integer anasurface (Draw_Interpretor& ,
            Standard_Integer  n, 
            const char** a)
{
  if (n < 2) return 1;
  gp_Ax3 loc;
​
  Standard_Integer i;
​
  if (n < 5) {
    loc = gp_Ax3(gp_Pnt(0,0,0),gp_Dir(0,0,1),gp_Dir(1,0,0));
    i = 2;
  }
  else if (n < 8) {
    loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
     gp_Dir(0,0,1),gp_Dir(1,0,0));
    i = 5;
  }
  else if (n < 11) {
    loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
     gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])));
    i = 8;
  }
  else if (n < 14) {
    loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
     gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
     gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10])));
    i = 11;
  }
  else
    return 1;
​
  Handle(Geom_Geometry) result;
​
  if (!strcasecmp(a[0],"plane")) {
    Handle(Geom_Plane) C = new Geom_Plane(loc);
    result = C;
  }
  else {
    if (i >= n) return 1;
    Standard_Real par1 = Draw::Atof(a[i]);
    
    if (!strcasecmp(a[0],"cylinder")) {
      Handle(Geom_CylindricalSurface) C = 
  new Geom_CylindricalSurface(loc,par1);
      result = C;
    }
    
    else if (!strcasecmp(a[0],"sphere")) {
      Handle(Geom_SphericalSurface) C = 
  new Geom_SphericalSurface(loc,par1);
      result = C;
    }
    
    else {
      if (i+1 >= n) return 1;
      Standard_Real par2 = Draw::Atof(a[i+1]);
      
      if (!strcasecmp(a[0],"cone")) {
  par1 *= (M_PI / 180.0);
  Handle(Geom_ConicalSurface) C =
    new Geom_ConicalSurface(loc,par1,par2);
  result = C;
      }
    
      else if (!strcasecmp(a[0],"torus")) {
  Handle(Geom_ToroidalSurface) C =
    new Geom_ToroidalSurface(loc,par1,par2);
  result = C;
      }
    }    
  }
​
  DrawTrSurf::Set(a[1],result);
  return 0;
}

转化为C++代码:

gp_Ax3 loc;Handle(Geom_Plane) p0 = new Geom_Plane(loc);

6、mkface rectangle1 p0 rectangle1

该命令的实现代码为:

static Standard_Integer mkface(Draw_Interpretor& , Standard_Integer n, const char** a)
{
  if (n < 3) return 1;
  
  Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[2]);
  if (S.IsNull()) {
    Message::SendFail() << a[2] << " is not a surface";
    return 1;
  }
  
  Standard_Boolean mkface = a[0][2] == 'f';
  TopoDS_Shape res;
​
  Standard_Boolean Segment = Standard_False;
  if ( !mkface && (n == 4 || n == 8)) {
    Segment = !strcmp(a[n-1],"1");
    n--;
  }
​
  if (n == 3) {
    if (mkface)
      res = BRepBuilderAPI_MakeFace(S, Precision::Confusion());
    else
      res = BRepBuilderAPI_MakeShell(S,Segment);
  }
  else if (n <= 5) {
    if (!mkface) return 1;
    Standard_Boolean orient = (n  == 4);
    TopoDS_Shape W = DBRep::Get(a[3],TopAbs_WIRE);
    if (W.IsNull()) return 1;
    res = BRepBuilderAPI_MakeFace(S,TopoDS::Wire(W),orient);
  }
  else {
    if (mkface)
      res = BRepBuilderAPI_MakeFace(S,Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]),Precision::Confusion());
    else
      res = BRepBuilderAPI_MakeShell(S,Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]),
            Segment);
  }
  
  DBRep::Set(a[1],res);
  return 0;
}

转化为C++代码:

TopoDS_Shape rectangle1f = BRepBuilderAPI_MakeFace(p0, TopoDS::Wire(rectangle1), Standard_True);

7、bcommon sec rectangle1 circle1

该命令的实现代码为:

Standard_Integer bcommon (Draw_Interpretor& di, 
                          Standard_Integer n, 
                          const char** a)
{
  return bsmt(di, n, a, BOPAlgo_COMMON);
}
​
Standard_Integer bsmt (Draw_Interpretor& di, 
                       Standard_Integer n, 
                       const char** a,
                       const BOPAlgo_Operation aOp)
{
  TopoDS_Shape aS1, aS2;
  TopTools_ListOfShape aLC;
  //
  if (n != 4) {
    di << " use bx r s1 s2\n";
    return 0;
  }
  //
  aS1=DBRep::Get(a[2]);
  aS2=DBRep::Get(a[3]);
  //
  if (aS1.IsNull() || aS2.IsNull()) {
    di << " null shapes are not allowed \n";
    return 0;
  }
  aLC.Append(aS1);
  aLC.Append(aS2);
  //
  Handle(NCollection_BaseAllocator)aAL=
    NCollection_BaseAllocator::CommonBaseAllocator();
  //
  BOPAlgo_BOP aBOP(aAL);
  aBOP.AddArgument(aS1);
  aBOP.AddTool(aS2);
  aBOP.SetOperation(aOp);
  // set options
  aBOP.SetGlue(BOPTest_Objects::Glue());
  aBOP.SetFuzzyValue(BOPTest_Objects::FuzzyValue());
  aBOP.SetNonDestructive(BOPTest_Objects::NonDestructive());
  aBOP.SetRunParallel(BOPTest_Objects::RunParallel());
  aBOP.SetUseOBB(BOPTest_Objects::UseOBB());
  aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
  aBOP.SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
  //
  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
  aBOP.Perform(aProgress->Start());
  BOPTest::ReportAlerts(aBOP.GetReport());
​
  // Store the history of Boolean operation into the session
  if (BRepTest_Objects::IsHistoryNeeded())
    BRepTest_Objects::SetHistory(aBOP.PDS()->Arguments(), aBOP);
​
  if (aBOP.HasErrors()) {
    return 0;
  }
  const TopoDS_Shape& aR=aBOP.Shape();
  if (aR.IsNull()) {
    di << " null shape\n";
    return 0;
  }
  //
  DBRep::Set(a[1], aR);
  return 0;
}

转化为C++代码:

TopoDS_Shape sec = BRepAlgoAPI_Common(rectangle1f, circle1f);

8、fuse sec sec circle2

该命令的实现代码为:

Standard_Integer bfuse (Draw_Interpretor& di, 
                        Standard_Integer n, 
                        const char** a)
{
  return bsmt(di, n, a, BOPAlgo_FUSE);
}
​
Standard_Integer bsmt (Draw_Interpretor& di, 
                       Standard_Integer n, 
                       const char** a,
                       const BOPAlgo_Operation aOp)
{
  TopoDS_Shape aS1, aS2;
  TopTools_ListOfShape aLC;
  //
  if (n != 4) {
    di << " use bx r s1 s2\n";
    return 0;
  }
  //
  aS1=DBRep::Get(a[2]);
  aS2=DBRep::Get(a[3]);
  //
  if (aS1.IsNull() || aS2.IsNull()) {
    di << " null shapes are not allowed \n";
    return 0;
  }
  aLC.Append(aS1);
  aLC.Append(aS2);
  //
  Handle(NCollection_BaseAllocator)aAL=
    NCollection_BaseAllocator::CommonBaseAllocator();
  //
  BOPAlgo_BOP aBOP(aAL);
  aBOP.AddArgument(aS1);
  aBOP.AddTool(aS2);
  aBOP.SetOperation(aOp);
  // set options
  aBOP.SetGlue(BOPTest_Objects::Glue());
  aBOP.SetFuzzyValue(BOPTest_Objects::FuzzyValue());
  aBOP.SetNonDestructive(BOPTest_Objects::NonDestructive());
  aBOP.SetRunParallel(BOPTest_Objects::RunParallel());
  aBOP.SetUseOBB(BOPTest_Objects::UseOBB());
  aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
  aBOP.SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
  //
  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
  aBOP.Perform(aProgress->Start());
  BOPTest::ReportAlerts(aBOP.GetReport());
​
  // Store the history of Boolean operation into the session
  if (BRepTest_Objects::IsHistoryNeeded())
    BRepTest_Objects::SetHistory(aBOP.PDS()->Arguments(), aBOP);
​
  if (aBOP.HasErrors()) {
    return 0;
  }
  const TopoDS_Shape& aR=aBOP.Shape();
  if (aR.IsNull()) {
    di << " null shape\n";
    return 0;
  }
  //
  DBRep::Set(a[1], aR);
  return 0;
}

转化为C++代码:

TopoDS_Shape secf = BRepAlgoAPI_Fuse(sec, circle2f);

9、cylinder cc 0 0 0 0 0 1 0 -4 0 4

该命令的实现代码为:

else if (n < 14) {
    loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
     gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
     gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10])));
    i = 11;
  }
​
else {
    if (i >= n) return 1;
    Standard_Real par1 = Draw::Atof(a[i]);
    
    if (!strcasecmp(a[0],"cylinder")) {
      Handle(Geom_CylindricalSurface) C = 
  new Geom_CylindricalSurface(loc,par1);
      result = C;
    }
​

转化为C++代码:

gp_Ax3 loccy = gp_Ax3(gp_Pnt(0, 0, 0),gp_Dir(0, 0, 1),gp_Dir(0, -4, 0));Handle(Geom_CylindricalSurface) cc =new Geom_CylindricalSurface(loccy, 4);

10、line ll 0 0 a 80

该命令的实现代码为:

if (!strcmp(a[0],"line")) {
    if (n == 6)
      result2d = new Geom2d_Line(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
         gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5])));
    else if (n == 8)
      result = new Geom_Line(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
           gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])));
    else
      return 1;
​
 

转化为C++代码:

Handle(Geom2d_Curve)  l1= new Geom2d_Line(gp_Pnt2d(0, 0),gp_Dir2d(a, 80.0));

11、trim ll ll 0 sqrt(a*a+H*H)

该命令的实现代码为:

static Standard_Integer trimming (Draw_Interpretor& , 
          Standard_Integer n, const char** a)
{
  if (n < 3) return 1;
​
  Handle(Geom_Curve)   GC   = DrawTrSurf::GetCurve(a[2]);
  Handle(Geom2d_Curve) GC2d = DrawTrSurf::GetCurve2d(a[2]);
  Handle(Geom_Surface) GS   = DrawTrSurf::GetSurface(a[2]);
​
  if (n == 3) {
    if (!GC.IsNull()) {
      Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(GC);
      if (!T.IsNull()) GC = T->BasisCurve();
      DrawTrSurf::Set(a[1],GC);
    }
    else if (!GC2d.IsNull()) {
      Handle(Geom2d_TrimmedCurve) T = Handle(Geom2d_TrimmedCurve)::DownCast(GC2d);
      if (!T.IsNull()) GC2d = T->BasisCurve();
      DrawTrSurf::Set(a[1],GC2d);
    }
    else if (!GS.IsNull()) {
      Handle(Geom_RectangularTrimmedSurface) T = Handle(Geom_RectangularTrimmedSurface)::DownCast(GS);
      if (!T.IsNull()) GS = T->BasisSurface();
      DrawTrSurf::Set(a[1],GS);
    }
    return 0;
  }
  
  if (n < 5) return 1;
​
  Standard_Real u1 = Draw::Atof(a[3]);
  Standard_Real u2 = Draw::Atof(a[4]);
​
  Standard_Real v1 = 0., v2 = 0.;
  Standard_Boolean USense = Standard_True, VSense = Standard_True;
​
  Handle(Geom_Geometry) result;
  Handle(Geom2d_Curve) result2d;
​
  if (!strcasecmp(a[0],"trim")) {
    if (!GS.IsNull()) {
      if (n<7) return 1;
      v1 = Draw::Atof(a[5]);
      v2 = Draw::Atof(a[6]);
      if (n > 7)
      {
        USense = *a[7] != '0';
        VSense = *a[8] != '0';
      }
      result =
  new Geom_RectangularTrimmedSurface(GS, u1, u2, v1, v2, USense, VSense);
    }
    else if (!GC.IsNull()) {
      if (n>5)
      {
        USense = *a[5] != '0';
      }
      result = new Geom_TrimmedCurve(GC, u1, u2, USense);
    }
    else if (!GC2d.IsNull()) {
      if (n > 5)
      {
        USense = *a[5] != '0';
      }
      result2d = new Geom2d_TrimmedCurve(GC2d, u1, u2, USense);
    }
    else
      return 1;
  }
  else {
    if (GS.IsNull()) return 1;
    Standard_Boolean Utrim = !strcasecmp(a[0], "trimu");
    if (n > 5)
      USense = *a[5] != '0';
    result =  new Geom_RectangularTrimmedSurface(GS, u1, u2, Utrim, USense);
  }
​
  if (!result.IsNull())
    DrawTrSurf::Set(a[1], result);
  else
    DrawTrSurf::Set(a[1],result2d);
  
  return 0;
}
​

转化为C++代码:

Handle(Geom2d_TrimmedCurve) l1tr = new Geom2d_TrimmedCurve(l1, 0, sqrt(a * a + H * H), Standard_True);

12、vertex v1 0 -R 0

该命令的实现代码为:

static Standard_Integer vertex(Draw_Interpretor& , Standard_Integer n, const char** a)
{
  if (n < 3) return 1;
  if (n >= 5) {
    DBRep::Set(a[1],
      BRepBuilderAPI_MakeVertex(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]))));
  }
  else if (n == 4)
  {
    TopoDS_Shape S = DBRep::Get(a[3]);
    if (S.IsNull()) return 0;
    if (S.ShapeType() != TopAbs_EDGE) return 0;
    BRepAdaptor_Curve C(TopoDS::Edge(S));
    gp_Pnt P;
    C.D0(Draw::Atof(a[2]),P);
    DBRep::Set(a[1], BRepBuilderAPI_MakeVertex(P));
  }
  else
  {
    Handle(DrawTrSurf_Point) aP =
      Handle(DrawTrSurf_Point)::DownCast(Draw::Get(a[2]));
    DBRep::Set(a[1], BRepBuilderAPI_MakeVertex(aP->Point()));
  }
  return 0;
}
​

转化为C++代码:

TopoDS_Vertex v1=BRepBuilderAPI_MakeVertex(gp_Pnt(0, -R, 0));

13、trotate v2 0 0 0 0 0 1 180.*a/pi

该命令的实现代码为:

static Standard_Integer transform(Draw_Interpretor&,Standard_Integer n,const char** a)
{
  if (n <= 1) return 1;
​
  gp_Trsf T;
  Standard_Integer last = n;
  const char* aName = a[0];
​
  Standard_Boolean isBasic = Standard_False;
  Standard_Boolean isForced = Standard_False;
  Standard_Boolean isCopy = Standard_False;
  Standard_Boolean isCopyMesh = Standard_False;
​
  // Check "copymesh" flag.
  if (!strcmp(a[n - 1], "-copymesh"))
  {
    isCopyMesh = Standard_True;
    last = --n;
  }
  // Check "copy" flag.
  if (!strcmp(a[n-1], "-copy")) {
    isCopy = Standard_True;
    last = --n;
  }
​
  if (!strcmp(aName,"reset")) {
  }
  else {
    isBasic = (aName[0] == 'b');
    isForced = (aName[0] == 'f');
​
    aName++;
​
    if (!strcmp(aName,"move")) {
      if (n < 3) return 1;
      TopoDS_Shape SL = DBRep::Get(a[n-1]);
      if (SL.IsNull()) return 0;
      T = SL.Location().Transformation();
      last = n-1;
      isBasic = Standard_True;
    }
    else if (!strcmp(aName,"translate")) {
      if (n < 5) return 1;
      T.SetTranslation(gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1])));
      last = n-3;
    }
    else if (!strcmp(aName,"rotate")) {
      if (n < 9) return 1;
      T.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(a[n-7]),Draw::Atof(a[n-6]),Draw::Atof(a[n-5])),
                    gp_Vec(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2]))),
                    Draw::Atof(a[n-1])* (M_PI / 180.0));
      last = n-7;
    }
    else if (!strcmp(aName,"mirror")) {
      if (n < 8) return 1;
      T.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(a[n-6]),Draw::Atof(a[n-5]),Draw::Atof(a[n-4])),
                  gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1]))));
​
      last = n-6;
    }
    else if (!strcmp(aName,"scale")) {
      if (n < 6) return 1;
      T.SetScale(gp_Pnt(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2])),Draw::Atof(a[n-1]));
      last = n-4;
    }
  }
​
  if (T.Form() == gp_Identity || isBasic || isForced) {
    Standard_Boolean isExeption = Standard_True;
    if (isForced)
    {
      isExeption = Standard_False;
    }
    TopLoc_Location L(T);
    for (Standard_Integer i = 1; i < last; i++) {
      TopoDS_Shape S = DBRep::Get(a[i]);
      if (S.IsNull())
      {
        Message::SendFail() << "Error: " << a[i] << " is not a valid shape";
        return 1;
      }
      else
      {
        try
        {
          if (!strcmp(aName, "move") || !strcmp(aName, "reset"))
          {
            DBRep::Set(a[i], S.Located(L, isExeption));
          }
          else
          {
            DBRep::Set(a[i], S.Moved(L, isExeption));
          }
        }
        catch (const Standard_DomainError&)
        {
          TCollection_AsciiString aScale(T.ScaleFactor());
          Message::SendWarning() << "Operation is not done: " << aName << " is not a valid transformation - scale = " << aScale;
          return 0;
        }
      }
    }
  }
  else {
    BRepBuilderAPI_Transform trf(T);
    for (Standard_Integer i = 1; i < last; i++) {
      TopoDS_Shape S = DBRep::Get(a[i]);
      if (S.IsNull()) {
        Message::SendFail() << "Error: " << a[i] << " is not a valid shape";
        return 1;
      }
      else {
        trf.Perform(S, isCopy, isCopyMesh);
        if (!trf.IsDone())
          return 1;
        DBRep::Set(a[i],trf.Shape());
      }
    }
  }
  return 0;
}
​

转化为C++代码:

gp_Trsf T;T.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0),gp_Vec(0, 0, 1)), 180. * a / M_PI);BRepBuilderAPI_Transform trf(T);trf.Perform(v2, Standard_False, Standard_False);TopoDS_Shape v2r = trf.Shape();

14、mksweep sp

该命令的实现代码为:

static Standard_Integer mksweep(Draw_Interpretor& di,
  Standard_Integer n, const char** a)
{
  if (n != 2 && n != 5) return 1;
  TopoDS_Shape Spine = DBRep::Get(a[1], TopAbs_WIRE);
  if (Spine.IsNull()) return 1;
  if (Sweep != 0)  {
    delete Sweep;
    Sweep = 0;
  }
​
  if (n > 2 && n <= 5)
  {
    if (!strcmp(a[2], "-C"))
    {
      ShapeUpgrade_UnifySameDomain aUnif(Spine, Standard_True, Standard_False, Standard_True);
​
      Standard_Real anAngTol = 5.;
      Standard_Real aLinTol = 0.1;
​
      if (n == 5)
      {
        anAngTol = Draw::Atof(a[3]);
        aLinTol = Draw::Atof(a[4]);
      }
​
      aUnif.SetAngularTolerance(anAngTol * M_PI / 180.);
      aUnif.SetLinearTolerance(aLinTol);
      aUnif.Build();
      Spine = aUnif.Shape();
      if (BRepTest_Objects::IsHistoryNeeded())
      {
        BRepTest_Objects::SetHistory(aUnif.History());
      }
    }
    else
    {
      di << "To correct input spine use 'mksweep wire -C [AngTol LinTol]'\n";
      di << "By default, AngTol = 5, LinTol = 0.1";
      return 1;
    }
  }
​
  Sweep = new BRepOffsetAPI_MakePipeShell(TopoDS::Wire(Spine));
  return 0;
}
​

转化为C++代码:

BRepOffsetAPI_MakePipeShell* Sweep = new BRepOffsetAPI_MakePipeShell(TopoDS::Wire(sp));

15、setsweep -G gg 0 0

该命令的实现代码为:

static Standard_Integer setsweep(Draw_Interpretor& di,
  Standard_Integer n, const char** a)
{
  if (n == 1) {
    di << "setsweep options [arg1 [arg2 [...]]] : options are :\n";
    di << "   -FR : Tangent and Normal are given by Frenet trihedron\n";
    di << "   -CF : Tangente is given by Frenet,\n";
    di << "         the Normal is computed to minimize the torsion \n";
    di << "   -DT : discrete trihedron\n";
    di << "   -DX Surf : Tangent and Normal are given by Darboux trihedron,\n";
    di << "       Surf have to be a shell or a face\n";
    di << "   -CN dx dy dz : BiNormal is given by dx dy dz\n";
    di << "   -FX Tx Ty TZ [Nx Ny Nz] : Tangent and Normal are fixed\n";
    di << "   -G guide  0|1(Plan|ACR)  0|1|2(no contact|contact|contact on border) : with guide\n";
    di << "   -SM : Set the maximum degree of approximation\n";
    di << "         paramvalue more then 0 (100 by default)\n";
    di << "   -DM : Set the maximum number of span of approximation\n";
    di << "         paramvalue [1; 14] (11 by default)\n";
    return 0;
  }
​
  if (Sweep == 0) {
    di << "You have forgotten the <<mksweep>> command  !\n";
    return 1;
  }
  if (!strcmp(a[1], "-FR")) {
    Sweep->SetMode(Standard_True);
  }
  else if (!strcmp(a[1], "-CF")) {
    Sweep->SetMode(Standard_False);
  }
  else if (!strcmp(a[1], "-DT")) {
    Sweep->SetDiscreteMode();
  }
  else if (!strcmp(a[1], "-DX")) {
    if (n != 3) {
      di << "bad arguments !\n";
      return 1;
    }
    TopoDS_Shape Surf;
    Surf = DBRep::Get(a[2], TopAbs_SHAPE);
    if (Surf.IsNull()) {
      di << a[2] << "is not a shape !\n";
      return 1;
    }
    Sweep->SetMode(Surf);
  }
  else if (!strcmp(a[1], "-CN")) {
    if (n != 5) {
      di << "bad arguments !\n";
      return 1;
    }
    gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
    Sweep->SetMode(D);
  }
  else if (!strcmp(a[1], "-FX")) {
    if ((n != 5) && (n != 8)) {
      di << "bad arguments !\n";
      return 1;
    }
    gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
    if (n == 8) {
      gp_Dir DN(Draw::Atof(a[5]), Draw::Atof(a[6]), Draw::Atof(a[7]));
      gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D, DN);
      Sweep->SetMode(Axe);
    }
    else {
      gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D);
      Sweep->SetMode(Axe);
    }
  }
  else if (!strcmp(a[1], "-G"))  // contour guide
  {
    if (n != 5)
    {
      di << "bad arguments !\n";
      return 1;
    }
    else
    {
      TopoDS_Shape Guide = DBRep::Get(a[2], TopAbs_WIRE);
      Standard_Boolean CurvilinearEquivalence = Draw::Atoi(a[3]) != 0;
      Standard_Integer KeepContact = Draw::Atoi(a[4]);
      Sweep->SetMode(TopoDS::Wire(Guide),
        CurvilinearEquivalence,
        (BRepFill_TypeOfContact)KeepContact);
    }
  }
  else if (!strcmp(a[1], "-DM"))
  {
    if (n != 3)
    {
      di << "bad arguments !\n";
      return 1;
    }
​
    if (Draw::Atoi(a[2]) > 0 && Draw::Atoi(a[2]) < 15)
    {
      Sweep->SetMaxDegree(Draw::Atoi(a[2]));
    }
    else
    {
      di << " -DM paramvalue must be [1; 14]\n";
      return 1;
    }
  }
  else if (!strcmp(a[1], "-SM"))
  {
    if (n != 3)
    {
      di << "bad arguments !\n";
      return 1;
    }
​
    if (Draw::Atoi(a[2]) > 0)
    {
      Sweep->SetMaxSegments(Draw::Atoi(a[2]));
    }
    else
    {
      di << " -SM paramvalue must be more then 0\n";
      return 1;
    }
  }
​
  else {
    di << "The option " << a[1] << " is unknown !\n";
    return 1;
  }
  return 0;
}
​

转化为C++代码:

Sweep->SetMode(TopoDS::Wire(gg), Standard_False,(BRepFill_TypeOfContact)0);

16、addsweep lip

该命令的实现代码为:

static Standard_Integer addsweep(Draw_Interpretor& di,
  Standard_Integer n, const char** a)
{
  if (n == 1) {
    di << "addsweep wire/vertex [Vertex] [-T] [-R] [u0 v0 u1 v1 [...[uN vN]]] : options are :\n";
    di << "   -T : the wire/vertex have to be translated to assume contact\n";
    di << "        with the spine\n";
    di << "   -R : the wire have to be rotated to assume orthogonality\n";
    di << "        with the spine's tangent\n";
    return 0;
  }
​
  if (Sweep == 0) {
    di << "You have forgotten the <<mksweep>> command  !\n";
    return 1;
  }
​
  TopoDS_Shape  Section;
  TopoDS_Vertex Vertex;
  Handle(Law_Interpol) thelaw;
​
  Section = DBRep::Get(a[1], TopAbs_SHAPE);
  if (Section.IsNull() ||
    (Section.ShapeType() != TopAbs_WIRE &&
    Section.ShapeType() != TopAbs_VERTEX))
  {
    di << a[1] << " is not a wire and is not a vertex!\n";
    return 1;
  }
​
  Standard_Boolean HasVertex = Standard_False,
    isT = Standard_False,
    isR = Standard_False;
​
  if (n > 2) {
    Standard_Integer cur = 2;
    // Reading of Vertex
    TopoDS_Shape InputVertex(DBRep::Get(a[cur], TopAbs_VERTEX));
    Vertex = TopoDS::Vertex(InputVertex);
    if (!Vertex.IsNull()) {
      cur++;
      HasVertex = Standard_True;
    }
​
    // Reading of the translation option
    if ((n > cur) && !strcmp(a[cur], "-T")) {
      cur++;
      isT = Standard_True;
    }
​
    // Reading of the rotation option
    if ((n > cur) && !strcmp(a[cur], "-R")) {
      cur++;
      isR = Standard_True;
    }
​
    // law ?
    if (n > cur) {
      Standard_Integer nbreal = n - cur;
      if ((nbreal < 4) || (nbreal % 2 != 0)) {
        //std::cout << "bad arguments ! :" <<a[cur] << std::endl;
        di << "bad arguments ! :" << a[cur] << "\n";
      }
      else { //law of interpolation
        Standard_Integer ii, L = nbreal / 2;
        TColgp_Array1OfPnt2d ParAndRad(1, L);
        for (ii = 1; ii <= L; ii++, cur += 2) {
          ParAndRad(ii).SetX(Draw::Atof(a[cur]));
          ParAndRad(ii).SetY(Draw::Atof(a[cur + 1]));
        }
        thelaw = new (Law_Interpol)();
        thelaw->Set(ParAndRad,
          Abs(ParAndRad(1).Y() - ParAndRad(L).Y()) < Precision::Confusion());
      }
    }
  }
​
  if (thelaw.IsNull()) {
    if (HasVertex) Sweep->Add(Section, Vertex, isT, isR);
    else           Sweep->Add(Section, isT, isR);
  }
  else {
    if (HasVertex) Sweep->SetLaw(Section, thelaw, Vertex, isT, isR);
    else           Sweep->SetLaw(Section, thelaw, isT, isR);
  }
​
  return 0;
}
​

转化为C++代码:

Sweep->Add(lip, Standard_False, Standard_False);

17、buildsweep spiral -S

该命令的实现代码为:

static Standard_Integer buildsweep(Draw_Interpretor& di,
  Standard_Integer n, const char** a)
{
  if (n == 1) {
    di << "build sweep result [-M/-C/-R] [-S] [tol] : options are\n";
    di << "   -M : Discontinuities are treated by Modification of\n";
    di << "        the sweeping mode : it is the default\n";
    di << "   -C : Discontinuities are treated like Right Corner\n";
    di << "        Treatment is Extent && Intersect\n";
    di << "   -R : Discontinuities are treated like Round Corner\n";
    di << "        Treatment is Intersect and Fill\n";
    di << "   -S : To build a Solid\n";
    return 0;
  }
​
  Standard_Boolean mksolid = Standard_False;
  if (Sweep == 0) {
    di << "You have forgotten the <<mksweep>> command  !\n";
    return 1;
  }
​
  if (!Sweep->IsReady()) {
    di << "You have forgotten the <<addsweep>> command  !\n";
    return 1;
  }
​
  TopoDS_Shape result;
  Standard_Integer cur = 2;
  if (n > cur) {
    BRepBuilderAPI_TransitionMode Transition = BRepBuilderAPI_Transformed;
​
    // Reading Transition
    if (!strcmp(a[cur], "-C")) {
      Transition = BRepBuilderAPI_RightCorner;
      cur++;
    }
    else if (!strcmp(a[cur], "-R")) {
      Transition = BRepBuilderAPI_RoundCorner;
      cur++;
    }
    Sweep->SetTransitionMode(Transition);
  }
  // Reading solid ?
  if ((n > cur) && (!strcmp(a[cur], "-S"))) mksolid = Standard_True;
​
  // Calcul le resultat
  Sweep->Build();
  if (!Sweep->IsDone()) {
    di << "Buildsweep : Not Done\n";
    BRepBuilderAPI_PipeError Stat = Sweep->GetStatus();
    if (Stat == BRepBuilderAPI_PlaneNotIntersectGuide) {
      di << "Buildsweep : One Plane not intersect the guide\n";
    }
    if (Stat == BRepBuilderAPI_ImpossibleContact) {
      di << "BuildSweep : One section can not be in contact with the guide\n";
    }
  }
  else {
    if (mksolid) {
      Standard_Boolean B;
      B = Sweep->MakeSolid();
      if (!B) di << " BuildSweep : It is impossible to make a solid !\n";
    }
    result = Sweep->Shape();
    DBRep::Set(a[1], result);
    // Save history of sweep
    if (BRepTest_Objects::IsHistoryNeeded())
    {
      TopTools_ListOfShape aList;
      Sweep->Profiles(aList);
      TopoDS_Shape aSpine = Sweep->Spine();
      aList.Append(aSpine);
      BRepTest_Objects::SetHistory(aList, *Sweep);
    }
  }
​
  return 0;
}
​

转化为C++代码:

BRepOffsetAPI_MakePipeShell* Sweep = new BRepOffsetAPI_MakePipeShell(TopoDS::Wire(sp));
Sweep->SetMode(TopoDS::Wire(gg), Standard_False,(BRepFill_TypeOfContact)0);
Sweep->Add(lip, Standard_False, Standard_False);
Sweep->Build();
TopoDS_Shape spiral = Sweep->Shape();

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值