青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

eryar

PipeCAD - Plant Piping Design Software.
PlantAssistant - Translate AVEVA RVM/SP3D VUE to glTF, STEP, etc.
posts - 606, comments - 590, trackbacks - 0, articles - 0

Geometry Surface of OpenCascade BRep

Posted on 2013-12-02 23:03 eryar 閱讀(4633) 評論(5)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

Geometry Surface of OpenCascade BRep

eryar@163.com

摘要Abstract:幾何曲面是參數表示的曲面 ,在邊界表示中其數據存在于BRep_TFace中,BRep_TFace中不僅包括了幾何曲線,還包含用于顯示的離散幾何信息,如三角剖分數據。本文主要對OpenCascade的BRep表示中幾何曲面進行說明,將在后面分析Topology部分的讀寫程序時來說明包含幾何數據的三種拓樸結構中分別包括哪些幾何信息。

關鍵字Key Words:OpenCascade BRep, Geometry Surface, Topology

一、引言 Introduction

邊界表示(Boundary Representation)也稱為BRep表示,它是幾何造型中最成熟、無二義的表示法。實體的邊界通常是由面的并集來表示,而每個面又由它所在的曲面的定義加上其邊界來表示,面的邊界是邊的并集,而邊又是由點來表示的。

邊界表示的一個重要特征是描述形體的信息包括幾何信息(Geometry)和拓樸信息(Topology)兩個方面。拓樸信息描述形體上的頂點、邊、面的連接關系,它形成物體邊界表示的“骨架”。形體的幾何信息猶如附著在“骨架”上的肌肉。例如,形體的某個面位于某一個曲面上,定義這一曲面方程的數據就是幾何信息。此外,邊的形狀、頂點在三維空間中的位置(點的坐標)等都是幾何信息,一般來說,幾何信息描述形體的大小、尺寸、位置和形狀等。

OpenCascade中幾何(Geometry)與拓樸(Topology)的關系也是按上述方式組織的。即幾何信息在BRep中并不是單獨存在的,而是依附于拓樸存在的。通過繼承TopoDS包中的抽象的拓樸類實現了邊界表示(BRep)模型。如下圖所示:

wps_clip_image-1308

Figure 1.1 Topology data structure in OpenCascade

從上面的類圖可以看出只有三種拓樸對象有幾何數據:頂點(vertex)、邊(edge)、面(face),分別為BRep_TVertex、BRep_TEdge、BRep_TFace。BRep_TVertex中主要包含一個空間點(x, y, z)數據;幾何曲線數據主要存在于BRep_TEdge中,BRep_TEdge中不僅包括了幾何曲線,還包含其他類型的幾何信息;BRep_TFace中主要包含幾何曲面及其他的幾何數據,如面的三角剖分等。本文主要對OpenCascade的BRep表示中幾何曲面進行說明,將在后面分析Topology部分的讀寫程序時來說明這三種拓樸結構中分別包括哪些幾何信息。

Draw Test Harness是OpenCascade提供的一種靈活和簡便的測試與演示OCCT造型庫的工具。他不僅可以使用交互的方式來創建、顯示和修改曲線、曲面和拓樸形狀,還可以以腳本(script)的方式來使用,OpenCascade就是用腳本的方式來對其造型內核進行自動化測試(Tests)。本文將示例程序的幾何曲面在Draw Test Harness進行創建與顯示,結合圖形的直觀顯示便于對抽象概念的理解。

二、示例程序 Example Code

在OpenCascade提供的文檔《BRep Format Description White Paper》對其BRep文件數據進行了說明。BRep文件的幾何部分包含了參數曲面,根據文檔中提供的數據,利用其提供的類來將示例數據進行輸出,再調試其相關代碼來分析其實現。示例程序如下所示:

 

/*
*    Copyright (c) 2013 eryar All Rights Reserved.
*
*           File : Main.cpp
*         Author : eryar@163.com
*           Date : 2013-12-01 12:18
*        Version : 1.0v
*
*    Description : Demonstrate the geometry surface section 
*                  of the BRep file of OpenCascade.
*       KeyWords : OpenCascade, BRep File, Geometry Surface
*                  
*/

// OpenCascade library.
#define WNT
#include 
<Geom_Plane.hxx>
#include 
<Geom_CylindricalSurface.hxx>
#include 
<Geom_ConicalSurface.hxx>
#include 
<Geom_SphericalSurface.hxx>
#include 
<Geom_ToroidalSurface.hxx>
#include 
<Geom_SurfaceOfLinearExtrusion.hxx>
#include 
<Geom_SurfaceOfRevolution.hxx>
#include 
<Geom_BezierSurface.hxx>
#include 
<Geom_BSplineSurface.hxx>
#include 
<Geom_RectangularTrimmedSurface.hxx>
#include 
<Geom_OffsetSurface.hxx>

#include 
<TColgp_Array2OfPnt.hxx>
#include 
<TColStd_Array1OfReal.hxx>
#include 
<TColStd_Array2OfReal.hxx>
#include 
<TColStd_Array1OfInteger.hxx>

#include 
<GeomTools.hxx>
#include 
<Geom_Circle.hxx>

#pragma comment(lib, 
"TKernel.lib")
#pragma comment(lib, 
"TKMath.lib")
#pragma comment(lib, 
"TKG3d.lib")
#pragma comment(lib, 
"TKGeomBase.lib")

int main(void)
{
    gp_Ax2 axis(gp_Pnt(
123), gp::DZ());
    std::ofstream dumpFile(
"geometrySurface.txt");

    
// Surface record 1 - Plane.
    
// Example: 1 0 0 3 0 0 1 1 0 -0 -0 1 0
    Handle_Geom_Plane thePlane = new Geom_Plane(gp_Pnt(003), gp_Dir(001));
    GeomTools::Write(thePlane, dumpFile);
    GeomTools::Dump(thePlane, dumpFile);
    GeomTools::Write(thePlane, std::cout);
    GeomTools::Dump(thePlane, std::cout);

    
// Surface record 2 - Cylinder.
    
// Example: 2 1 2 3 0 0 1 1 0 0 0 1 0 4
    Handle_Geom_CylindricalSurface theCylinder = new Geom_CylindricalSurface(axis, 4.0);
    GeomTools::Write(theCylinder, dumpFile);
    GeomTools::Dump(theCylinder, dumpFile);
    GeomTools::Write(theCylinder, std::cout);
    GeomTools::Dump(theCylinder, std::cout);

    
// Surface record 3 - Cone.
    
// Example: 3 1 2 3 0 0 1 1 0 0 0 1 0 4
    
//          0.75
    Handle_Geom_ConicalSurface theCone = new Geom_ConicalSurface(axis, 0.754.0);
    GeomTools::Write(theCone, dumpFile);
    GeomTools::Dump(theCone, dumpFile);
    GeomTools::Write(theCone, std::cout);
    GeomTools::Dump(theCone, std::cout);

    
// Surface record 4 - Sphere.
    
// Example: 4 1 2 3 0 0 1 1 0 -0 -0 1 0 4
    Handle_Geom_SphericalSurface theSphere = new Geom_SphericalSurface(axis, 4);
    GeomTools::Write(theSphere, dumpFile);
    GeomTools::Dump(theSphere, dumpFile);
    GeomTools::Write(theSphere, std::cout);
    GeomTools::Dump(theSphere, std::cout);

    
// Surface record 5 - Torus.
    
// Example: 5 1 2 3 0 0 1 1 0 -0 -0 1 0 8 4
    Handle_Geom_ToroidalSurface theTorus = new Geom_ToroidalSurface(axis, 84);
    GeomTools::Write(theTorus, dumpFile);
    GeomTools::Dump(theTorus, dumpFile);
    GeomTools::Write(theTorus, std::cout);
    GeomTools::Dump(theTorus, std::cout);

    
// Surface record 6 - Linear Extrusion.
    
// Example: 6 0 0.6 0.8 
    
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
    Handle_Geom_Circle baseCurve = new Geom_Circle(axis, 4.0);
    Handle_Geom_SurfaceOfLinearExtrusion theExtrusion 
= new Geom_SurfaceOfLinearExtrusion(baseCurve, gp_Dir(00.60.8));
    GeomTools::Write(theExtrusion, dumpFile);
    GeomTools::Dump(theExtrusion, dumpFile);
    GeomTools::Write(theExtrusion, std::cout);
    GeomTools::Dump(theExtrusion, std::cout);

    
// Surface record 7 - Revolution Surface.
    
// Example: 7 -4 0 3 0 1 0 
    
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
    Handle_Geom_SurfaceOfRevolution theRevolution = new Geom_SurfaceOfRevolution(baseCurve, gp::OY());
    theRevolution
->SetLocation(gp_Pnt(-403));
    GeomTools::Write(theRevolution, dumpFile);
    GeomTools::Dump(theRevolution, dumpFile);
    GeomTools::Write(theRevolution, std::cout);
    GeomTools::Dump(theRevolution, std::cout);

    
// Surface record 8 - Bezier Surface.
    
// Example: 8 1 1 2 1 0 0 1  7 1 0 -4  10 
    
//          0 1 -2  8 1 1 5  11 
    
//          0 2 3  9 1 2 6  12 
    TColgp_Array2OfPnt poles(1312);
    TColStd_Array2OfReal weights(
1312);

    poles.SetValue(
11, gp_Pnt(001));      weights.SetValue(117.0);
    poles.SetValue(
12, gp_Pnt(10-4));     weights.SetValue(1210.0);

    poles.SetValue(
21, gp_Pnt(01-2));     weights.SetValue(218.0);
    poles.SetValue(
22, gp_Pnt(115));      weights.SetValue(2211.0);

    poles.SetValue(
31, gp_Pnt(023));      weights.SetValue(319.0);
    poles.SetValue(
32, gp_Pnt(126));      weights.SetValue(3212.0);

    Handle_Geom_BezierSurface theBezierSurface 
= new Geom_BezierSurface(poles, weights);
    GeomTools::Write(theBezierSurface, dumpFile);
    GeomTools::Dump(theBezierSurface, dumpFile);
    GeomTools::Write(theBezierSurface, std::cout);
    GeomTools::Dump(theBezierSurface, std::cout);

    
// Surface record 9 - B-spline Surface.
    
// Example: 9 1 1 0 0 1 1 3 2 5 4 0 0 1  7 1 0 -4  10 
    
//          0 1 -2  8 1 1 5  11 
    
//          0 2 3  9 1 2 6  12 
    
//
    
//          0 1
    
//          0.25 1
    
//          0.5 1
    
//          0.75 1
    
//          1 1
    
//
    
//          0 1
    
//          0.3 1
    
//          0.7 1
    
//          1 1
    Standard_Integer uDegree = 1;
    Standard_Integer vDegree 
= 1;
    Standard_Boolean uPeriodic 
= Standard_False;
    Standard_Boolean vPeriodic 
= Standard_False;

    TColStd_Array1OfReal uKnots(
15);
    TColStd_Array1OfReal vKnots(
14);
    TColStd_Array1OfInteger uMults(
15);
    TColStd_Array1OfInteger vMults(
14);

    uKnots.SetValue(
10);
    uKnots.SetValue(
20.25);
    uKnots.SetValue(
30.5);
    uKnots.SetValue(
40.75);
    uKnots.SetValue(
51.0);

    vKnots.SetValue(
10);
    vKnots.SetValue(
20.3);
    vKnots.SetValue(
30.7);
    vKnots.SetValue(
41.0);

    
// Multiplicity of u and v are 1.
    uMults.Init(1);
    vMults.Init(
1);

    Handle_Geom_BSplineSurface theBSplineSurface 
= new Geom_BSplineSurface(poles, weights, uKnots, vKnots, uMults, vMults, uDegree, vDegree, uPeriodic, vPeriodic);
    GeomTools::Write(theBSplineSurface, dumpFile);
    GeomTools::Dump(theBSplineSurface, dumpFile);
    GeomTools::Write(theBSplineSurface, std::cout);
    GeomTools::Dump(theBSplineSurface, std::cout);

    
// Surface record 10 - Rectangular Trim Surface.
    
// Example: 10 -1 2 -3 4
    
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0 
    Handle_Geom_Plane baseSurface = new Geom_Plane(axis);
    Handle_Geom_RectangularTrimmedSurface theTrimmedSurface 
= new Geom_RectangularTrimmedSurface(baseSurface, -1.02.0-3.04.0);
    GeomTools::Write(theTrimmedSurface, dumpFile);
    GeomTools::Dump(theTrimmedSurface, dumpFile);
    GeomTools::Write(theTrimmedSurface, std::cout);
    GeomTools::Dump(theTrimmedSurface, std::cout);

    
// Surface record 11 - Offset Surface.
    
// Example: 11 -2
    
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0 
    Handle_Geom_OffsetSurface theOffsetSurface = new Geom_OffsetSurface(baseSurface, -2.0);
    GeomTools::Write(theOffsetSurface, dumpFile);
    GeomTools::Dump(theOffsetSurface, dumpFile);
    GeomTools::Write(theOffsetSurface, std::cout);
    GeomTools::Dump(theOffsetSurface, std::cout);

    
return 0;
}

上述程序將《BRep Format Description White Paper》中的幾何部分(Geometry Section)的參數曲面(Surfaces)示例數據分別使用類GeomTools的靜態函數輸出到屏幕和文件。

當使用GeomTools::Write()時輸出的內容與BRep文件中一致,當使用GeomTools::Dump()時輸出更易讀的信息。為了便于對比理解,將兩種形式都輸出到文件geometrySurface.txt中,輸出數據如下所示:

1 0 0 3 0 0 1 1 0 -0 -0 1 0 
Plane
  Origin :
003 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 

2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
CylindricalSurface
  Origin :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 
  Radius :
4

3 1 2 3 0 0 1 1 0 -0 -0 1 0 4
0.75
ConicalSurface
  Origin :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 
  Radius :
4

  Angle :
0.75

4 1 2 3 0 0 1 1 0 -0 -0 1 0 4
SphericalSurface
  Center :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 
  Radius :
4

5 1 2 3 0 0 1 1 0 -0 -0 1 0 8 4
ToroidalSurface
  Origin :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 
  Radii  :
8 4

6 0 0.6 0.8 
2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
SurfaceOfLinearExtrusion
  Direction :
00.60.8 
  Basis curve : 
Circle
  Center :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 
  Radius :
4

7 -4 0 3 0 1 0 
2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
SurfaceOfRevolution
  Origin    :
-403 
  Direction :
010 
  Basis curve : 
Circle
  Center :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 
  Radius :
4

8 1 1 2 1 0 0 1  7 1 0 -4  10 
0 1 -2  8 1 1 5  11 
0 2 3  9 1 2 6  12 

BezierSurface urational vrational
  Degrees :
2 1 
   
1,  1 : 001  7
   
1,  2 : 10-4  10

   
2,  1 : 01-2  8
   
2,  2 : 115  11

   
3,  1 : 023  9
   
3,  2 : 126  12


9 1 1 0 0 1 1 3 2 5 4 0 0 1  7 1 0 -4  10 
0 1 -2  8 1 1 5  11 
0 2 3  9 1 2 6  12 

0 1
0.25 1
0.5 1
0.75 1
1 1

0 1
0.3 1
0.7 1
1 1

BSplineSurface urational vrational
  Degrees :
1 1 
  NbPoles :
3 2 
  NbKnots :
5 4 
 Poles :

   
1,  1 : 001  7
   
1,  2 : 10-4  10

   
2,  1 : 01-2  8
   
2,  2 : 115  11

   
3,  1 : 023  9
   
3,  2 : 126  12


 UKnots :

   
1 : 0 1

   
2 : 0.25 1

   
3 : 0.5 1

   
4 : 0.75 1

   
5 : 1 1


 VKnots :

   
1 : 0 1

   
2 : 0.3 1

   
3 : 0.7 1

   
4 : 1 1


10 -1 2 -3 4
1 1 2 3 0 0 1 1 0 -0 -0 1 0 
RectangularTrimmedSurface
Parameters : 
-1 2 -3 4
BasisSurface :
Plane
  Origin :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 

11 -2
1 1 2 3 0 0 1 1 0 -0 -0 1 0 
OffsetSurface
Offset : 
-2
BasisSurface :
Plane
  Origin :
123 
  Axis   :
001 
  XAxis  :
10-0 
  YAxis  :
-010 

 

三、程序說明 Example Description

3.1 平面 Plane

示例:

// Surface record 1 - Plane.
// Example: 1 0 0 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_Plane thePlane = new Geom_Plane(gp_Pnt(003), gp_Dir(001));
GeomTools::Write(thePlane, dumpFile);
GeomTools::Dump(thePlane, dumpFile);

<surface record 1>定義了平面。平面數據包含三維點P和三維正交坐標系N,Du,Dv。平面通過點P,且其法向量為N。其參數方程如下所示:

wps_clip_image-11298

示例數據表示的平面為通過點P=(0,0,3),法向量N=(0,0,1),其參數方程如下所示:

wps_clip_image-5784

在Draw Test Harness中創建并顯示平面如下所示:

wps_clip_image-22746

wps_clip_image-2580

3.2 圓柱面 Cylinder

示例:

 

// Surface record 2 - Cylinder.
// Example: 2 1 2 3 0 0 1 1 0 0 0 1 0 4
Handle_Geom_CylindricalSurface theCylinder = new Geom_CylindricalSurface(axis, 4.0);
GeomTools::Write(theCylinder, dumpFile);
GeomTools::Dump(theCylinder, dumpFile);

 

<surface record 2>定義了圓柱面。圓柱面的數據包含三維點P,三維正交坐標系Dv,Dx,Dy和一個非負實數r。圓柱面的軸通過點P,方向為Dv,圓柱面的半徑為r,其參數方程如下所示:

wps_clip_image-19091

示例數據表示的圓柱面為軸通過點P=(1,2,3),軸的方向Dv=(0,0,1),方向Dx=(1,0,-0),Dy=(-0,1,0),半徑r=4,其參數方程如下所示:

wps_clip_image-6144

在Draw Test Harness中創建并顯示圓柱面如下所示:

wps_clip_image-8358

wps_clip_image-6877

3.3 圓錐面 Cone

示例:

 

// Surface record 3 - Cone.
// Example: 3 1 2 3 0 0 1 1 0 0 0 1 0 4
//          0.75
Handle_Geom_ConicalSurface theCone = new Geom_ConicalSurface(axis, 0.754.0);
GeomTools::Write(theCone, dumpFile);
GeomTools::Dump(theCone, dumpFile);

<surface record 3>定義了圓錐面。圓錐面的數據包含三維點P,正交坐標系Dz,Dx,Dy,非負實數r和實數ψ(范圍為(-π/2, π/2))。圓錐面通過點P且軸的方向為Dz。過點P且與方向Dx,Dy平行的平面為圓錐面的參考平面(referenced plane)。參考平面截圓錐面為一個圓,其半徑為r。其參數方程如下所示:

wps_clip_image-31469

示例數據表示的圓錐面的軸通過點P=(1,2,3),方向Dz=(0,0,1)。圓錐面的其他數據是Dx=(1,0,-0),Dy=(-0,1,0),半徑r=4,角度ψ=0.75。其參數方程如下所示:

wps_clip_image-3344

在Draw Test Harness中創建并顯示圓錐面如下所示:

wps_clip_image-9316

wps_clip_image-1827

3.4 球面 Sphere

示例:

// Surface record 4 - Sphere.
// Example: 4 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_SphericalSurface theSphere = new Geom_SphericalSurface(axis, 4);
GeomTools::Write(theSphere, dumpFile);
GeomTools::Dump(theSphere, dumpFile);

 

<surface record 4>定義了球面。球面的數據包含三維點P,三維正交坐標系Dz,Dx,Dy和非負實數r。即球面的球心為點P,半徑為r,其參數方程如下所示:

wps_clip_image-28383

示例數據表示的球面為球心過點P=(1,2,3),方向分別為Dz=(0,0,1),Dx=(1,0,-0),Dy=(-0,1,0),半徑r=4。其參數方程如下所示:

wps_clip_image-10542

在Draw Test Harness中創建并顯示球面如下所示:

wps_clip_image-361

wps_clip_image-4147

3.5 圓環面 Torus

示例:

// Surface record 5 - Torus.
// Example: 5 1 2 3 0 0 1 1 0 -0 -0 1 0 8 4
Handle_Geom_ToroidalSurface theTorus = new Geom_ToroidalSurface(axis, 84);
GeomTools::Write(theTorus, dumpFile);
GeomTools::Dump(theTorus, dumpFile);

 

<surface record 5>定義了圓環面。圓環面的數據包含三維點P,三維正交坐標系Dz,Dx,Dy和非負實數r1,r2。圓環面的軸通過點P,方向為Dz,r1是從圓環面的圓的中心到點P的距離,圓環面的圓的半徑為r2。圓環面的參數方程如下所示:

wps_clip_image-22161

示例數據表示的圓環面的軸通過點P=(1,2,3),軸的方向為Dz=(0,0,1)。其它數據為Dx=(1,0,-0),Dy=(0,1,0),r1=8,r2=4,其參數方程如下所示:

wps_clip_image-16311

在Draw Test Harness中創建并顯示圓環面如下所示:

wps_clip_image-21043

wps_clip_image-26855

3.6 線性拉伸面 Linear Extrusion

示例:

// Surface record 6 - Linear Extrusion.
// Example: 6 0 0.6 0.8 
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_Circle baseCurve = new Geom_Circle(axis, 4.0);
Handle_Geom_SurfaceOfLinearExtrusion theExtrusion 
= new Geom_SurfaceOfLinearExtrusion(baseCurve, gp_Dir(00.60.8));
GeomTools::Write(theExtrusion, dumpFile);
GeomTools::Dump(theExtrusion, dumpFile);

 

<surface record 6>定義了線性拉伸面。線性拉伸面的數據包含三維方向Dv和三維曲線<3D curve record>。其參數方程如下所示:

wps_clip_image-21121

示例數據表示的線性拉伸面的拉伸方向Dv=(0,0.6,0.8),拉伸曲線為圓。拉伸面的參數方程如下所示:

wps_clip_image-1022

在Draw Test Harness中創建并顯示線性拉伸面如下所示:

wps_clip_image-32343

wps_clip_image-5581

3.7 旋轉面 Revolution Surface

示例:

// Surface record 7 - Revolution Surface.
// Example: 7 -4 0 3 0 1 0 
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_SurfaceOfRevolution theRevolution = new Geom_SurfaceOfRevolution(baseCurve, gp::OY());
theRevolution
->SetLocation(gp_Pnt(-403));
GeomTools::Write(theRevolution, dumpFile);
GeomTools::Dump(theRevolution, dumpFile);

 

<surface record 7>定義了旋轉面。旋轉面的數據包含三維點P,三維方向D和三維曲線。旋轉曲面的軸通過點P且方向為D,旋轉曲線為C與旋轉軸共面。旋轉曲面的參數方程如下所示:

wps_clip_image-25371

示例數據表示的旋轉曲面的旋轉軸通過點P=(-4,0,3),方向D=(0,1,0),旋轉曲線是一個圓。其參數方程如下所示:

wps_clip_image-2706

在Draw Test Harness中創建并顯示旋轉面如下所示:

wps_clip_image-18106

wps_clip_image-6277

3.8 Bezier曲面 Bezier Surface

示例:

// Surface record 8 - Bezier Surface.
// Example: 8 1 1 2 1 0 0 1  7 1 0 -4  10 
//          0 1 -2  8 1 1 5  11 
//          0 2 3  9 1 2 6  12 
TColgp_Array2OfPnt poles(1312);
TColStd_Array2OfReal weights(
1312);

poles.SetValue(
11, gp_Pnt(001));      weights.SetValue(117.0);
poles.SetValue(
12, gp_Pnt(10-4));     weights.SetValue(1210.0);

poles.SetValue(
21, gp_Pnt(01-2));     weights.SetValue(218.0);
poles.SetValue(
22, gp_Pnt(115));      weights.SetValue(2211.0);

poles.SetValue(
31, gp_Pnt(023));      weights.SetValue(319.0);
poles.SetValue(
32, gp_Pnt(126));      weights.SetValue(3212.0);

Handle_Geom_BezierSurface theBezierSurface 
= new Geom_BezierSurface(poles, weights);
GeomTools::Write(theBezierSurface, dumpFile);
GeomTools::Dump(theBezierSurface, dumpFile);

 

<surface record 8>定義了Bezier曲面。曲面的數據包含u有理標志位ru,v有理標志位rv,曲面次數mu, mv,和weight poles。u,v的次數都不能大于25。

當ru+rv=0時,weight poles是(mu+1)(mv+1)個三維點Bi,j((i,j)∈{0,...,mu}x{0,...,mv}),hi,j=1((i,j)∈{0,...,mu}x{0,...,mv});

當ru+rv≠0時,weight poles是(mu+1)(mv+1)個帶權控制點對Bi,j,hi,j。Bi,j是三維點,hi,j是權因子,正實數。

Bezier曲面的參數方程如下所示:

wps_clip_image-30345

示例數據表示的Bezier曲面為:u有理標志位ru=1,v有理標志位rv=1,次數mu=2,mv=1,weight poles為:B0,0=(0,0,1),h0,0=7,B0,1=(1,0,-4),h0,1=10,B1,0=(0,1,-2),h1,0=8,B1,1=(1,1,5),h1,1=11,B2,0=(0,2,3),h2,0=9,B2,1=(1,2,6),h2,1=12。曲面的參數方程為:

wps_clip_image-28608

在Draw Test Harness中創建并顯示Bezier曲面如下所示:

wps_clip_image-25092

wps_clip_image-27243

3.9 B樣條曲面 B-spline Surface

示例:

// Surface record 9 - B-spline Surface.
// Example: 9 1 1 0 0 1 1 3 2 5 4 0 0 1  7 1 0 -4  10 
//          0 1 -2  8 1 1 5  11 
//          0 2 3  9 1 2 6  12 
//
//          0 1
//          0.25 1
//          0.5 1
//          0.75 1
//          1 1
//
//          0 1
//          0.3 1
//          0.7 1
//          1 1
Standard_Integer uDegree = 1;
Standard_Integer vDegree 
= 1;
Standard_Boolean uPeriodic 
= Standard_False;
Standard_Boolean vPeriodic 
= Standard_False;

TColStd_Array1OfReal uKnots(
15);
TColStd_Array1OfReal vKnots(
14);
TColStd_Array1OfInteger uMults(
15);
TColStd_Array1OfInteger vMults(
14);

uKnots.SetValue(
10);
uKnots.SetValue(
20.25);
uKnots.SetValue(
30.5);
uKnots.SetValue(
40.75);
uKnots.SetValue(
51.0);

vKnots.SetValue(
10);
vKnots.SetValue(
20.3);
vKnots.SetValue(
30.7);
vKnots.SetValue(
41.0);

// Multiplicity of u and v are 1.
uMults.Init(1);
vMults.Init(
1);

Handle_Geom_BSplineSurface theBSplineSurface 
= new Geom_BSplineSurface(poles, weights, uKnots, vKnots, uMults, vMults, uDegree, vDegree, uPeriodic, vPeriodic);
GeomTools::Write(theBSplineSurface, dumpFile);
GeomTools::Dump(theBSplineSurface, dumpFile);

<surface record 9>定義了B-Spline曲面。B樣條曲面數據包含u有理標志位ru,v有理標志位rv,u次數mu<=25;v次數mv<=25,u控制點數nu>=2,v控制點數nv>=2,u重節點數ku,v重節點數kn,weight poles,u重節點,v重節點。

當ru+rv=0時,weight poles是(mu+1)(mv+1)個三維點Bi,j((i,j)∈{0,...,mu}x{0,...,mv}),hi,j=1((i,j)∈{0,...,mu}x{0,...,mv});

當ru+rv≠0時,weight poles是(mu+1)(mv+1)個帶權控制點對Bi,j,hi,j。Bi,j是三維點,hi,j是權因子,正實數。

u重節點及其重數有ku對:u1,q1,...,uku,qku。這里ui是重數為qi>=1的節點:

wps_clip_image-2252

v重節點及其重數有kv對:u1,q1,...,ukv,qkv。這里vi是重數為qi>=1的節點:

wps_clip_image-18265

B-Spline曲面的參數方程如下所示:

wps_clip_image-15698

基函數Ni,j和Mi,j有如下的遞歸定義:

wps_clip_image-2679

wps_clip_image-2572

wps_clip_image-14774

示例數據表示的B-Spline曲面為:u有理標志位ru=1,v有理標志位rv=1,u次數mu=1,v次數mv=1,u控制點數nu=3,v控制點數nv=2,u有重復度的節點數ku=5,v有重復度節點數kv=4,帶權控制點B1,1=(0,0,1),h1,1=7,B1,2=(1,0,-4),h1,2=10,B2,1=(0,1,-2),h2,1=8,B2,2=(1,1,5),h2,2=11,B3,1=(0,2,3),h3,1=9,B3,2=(1,2,6),h3,2=12,u有重復度節點u1=0,q1=1,u2=0.25,q2=1,u3=0.5,q3=1,u4=0.75,q4=1,u5=1,q5=1,v有重度度節點v1=0,r1=1,v2=0.3,r2=1,v3=0.7,r3=1,v4=1,r4=1。B-Spline曲面的參數方程如下所示:

wps_clip_image-13612

在Draw Test Harness中創建并顯示B樣條曲面如下所示:

wps_clip_image-8801

wps_clip_image-32556

3.10 矩形裁剪曲面 Rectangular Trim Surface

示例:

// Surface record 10 - Rectangular Trim Surface.
// Example: 10 -1 2 -3 4
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0 
Handle_Geom_Plane baseSurface = new Geom_Plane(axis);
Handle_Geom_RectangularTrimmedSurface theTrimmedSurface 
= new Geom_RectangularTrimmedSurface(baseSurface, -1.02.0-3.04.0);
GeomTools::Write(theTrimmedSurface, dumpFile);
GeomTools::Dump(theTrimmedSurface, dumpFile);

<surface record 10>定義了矩形裁剪曲面。矩形裁剪曲面的數據包含實數umin,umax,vmin,vmax和一個曲面。矩形裁剪曲面是將曲面限制在矩形區域[umin,umax]x[vmin,vmax]內得到的曲面。曲面的參數方程如下所示:

wps_clip_image-29176

示例數據表示的矩形裁剪曲面的矩形裁剪區域為[-1,2]x[-3,4],被裁剪曲面B(u,v)=(1,2,3)+u(1,0,0)+v(0,1,0)。其參數方程如下所示:

wps_clip_image-23222

在Draw Test Harness中創建并顯示矩形裁剪曲面如下所示:

wps_clip_image-1800

wps_clip_image-4258wps_clip_image-16788

3.11 偏移曲面 Offset Surface

示例:

// Surface record 11 - Offset Surface.
// Example: 11 -2
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0 
Handle_Geom_OffsetSurface theOffsetSurface = new Geom_OffsetSurface(baseSurface, -2.0);
GeomTools::Write(theOffsetSurface, dumpFile);
GeomTools::Dump(theOffsetSurface, dumpFile);

<surface record 11>定義了偏移曲面。偏移曲面的數據包含偏移距離d和曲面。偏移曲面的就將基準曲面B沒曲面的法向N上偏移距離d得到的曲面。偏移曲面的參數方程如下所示:

wps_clip_image-6442

示例數據表示的偏移曲面的偏移距離d=-2,基準曲面B(u,v)=(1,2,3)+u(1,0,0)+v(0,1,0)。其參數方程如下所示:

wps_clip_image-6164

在Draw Test Harness中創建并顯示偏移曲面如下所示:

wps_clip_image-31622

wps_clip_image-7440

注:當偏移-2時,效果不明顯示,所以偏移了-20,這樣看上去比較明顯。

四、程序分析 Refactoring the Code

wps_clip_image-20357

Figure 4.1 Class diagram of Geom_Surface

根據幾何曲面的類圖可知,幾何曲面有個共同的基類Geom_Surface。而在對幾何數據進行輸出與讀入時,用了很多條件判斷。輸出部分程序代碼如下所示:

 

//=======================================================================
//function : PrintSurface
//purpose  : 
//=======================================================================
void GeomTools_SurfaceSet::PrintSurface(const Handle(Geom_Surface)& S,
                    Standard_OStream
& OS,
                    
const Standard_Boolean compact)
{
  Handle(Standard_Type) TheType 
= S->DynamicType();

  
if ( TheType ==  STANDARD_TYPE(Geom_Plane)) {
    Print(Handle(Geom_Plane)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_CylindricalSurface)) {
    Print(Handle(Geom_CylindricalSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_ConicalSurface)) {
    Print(Handle(Geom_ConicalSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_SphericalSurface)) {
    Print(Handle(Geom_SphericalSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_ToroidalSurface)) {
    Print(Handle(Geom_ToroidalSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
    Print(Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
    Print(Handle(Geom_SurfaceOfRevolution)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_BezierSurface)) {
    Print(Handle(Geom_BezierSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_BSplineSurface)) {
    Print(Handle(Geom_BSplineSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
    Print(Handle(Geom_RectangularTrimmedSurface)::DownCast(S),OS,compact);
  }
  
else if ( TheType ==  STANDARD_TYPE(Geom_OffsetSurface)) {
    Print(Handle(Geom_OffsetSurface)::DownCast(S),OS,compact);
  }
  
else {
    GeomTools::GetUndefinedTypeHandler()
->PrintSurface(S,OS,compact);
    
//if (!compact)
    
//  OS << "***** Unknown Surface ********\n";
    
//else
    
//  cout << "***** Unknown Surface ********"<<endl;
  }
}

讀入部分的程序代碼如下所示:

 

//=======================================================================
//function : ReadSurface
//purpose  : 
//=======================================================================
Standard_IStream& GeomTools_SurfaceSet::ReadSurface(Standard_IStream& IS,
                            Handle(Geom_Surface)
& S)
{
  Standard_Integer stype;

  
try {
    OCC_CATCH_SIGNALS
    IS 
>> stype;
    
switch (stype) {

    
case PLANE :
      {
        Handle(Geom_Plane) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case CYLINDER :
      {
        Handle(Geom_CylindricalSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case CONE :
      {
        Handle(Geom_ConicalSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case SPHERE :
      {
        Handle(Geom_SphericalSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case TORUS :
      {
        Handle(Geom_ToroidalSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case LINEAREXTRUSION :
      {
        Handle(Geom_SurfaceOfLinearExtrusion) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case REVOLUTION :
      {
        Handle(Geom_SurfaceOfRevolution) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case BEZIER :
      {
        Handle(Geom_BezierSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case BSPLINE :
      {
        Handle(Geom_BSplineSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case RECTANGULAR :
      {
        Handle(Geom_RectangularTrimmedSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;

    
case OFFSET :
      {
        Handle(Geom_OffsetSurface) SS;
        IS 
>> SS;
        S 
= SS;
      }
      
break;
      
    
default :
      {
        Handle(Geom_Surface) SS;
        GeomTools::GetUndefinedTypeHandler()
->ReadSurface(stype,IS,SS);
        S 
= SS;
      }
      
break;
    }
  }
  
catch(Standard_Failure) {
#ifdef DEB
    Handle(Standard_Failure) anExc 
= Standard_Failure::Caught();
    cout 
<<"EXCEPTION in GeomTools_SurfaceSet::ReadSurface(..)!!!" << endl;
    cout 
<< anExc << endl;
#endif
    S 
= NULL;
  }
  
return IS;
}

正如《Refactoring-Improving the Design of Existing Code》書中以多態取代條件表達式(Replace Conditional with Polymorphism)所說,在面向對象術語中,聽上去最高貴的詞非“多態”莫屬。多態最根本的好處就是如果你需要根據對象的不同類型而采取不同的行為,多態使你不必編寫明顯的條件表達式。正因為有了多態,所以你會發現“類型碼的switch語句”以及“基于類型名稱的if-then-else語句”在面向對象程序中很少出現。

多態能夠帶給你很多好處。如果同一組條件表達式在程序許多地方出現,那么使用多態的收益是最大的。使用條件表達式時,如果你想添加一種新類型,就必須查找并更新所有條件表達式。但如果改用多態,只需要一個新的子類,并在其中提供適當的函數就行了。類的用戶不需要了解這個子類,這就大降低了系統各部分之間的依賴,使系統升級更容易。

OpenCascade的幾何曲面已經有一個基類Geom_Surface了,可將輸出做為虛函數,就不需要做判斷了。在讀入(創建)時引入工廠模式,對于UndefinedTypeHandler()可以引入Null對象。經過這樣重構之后的程序可讀性應該會更好吧!

五、結論 Conclusion

在邊界表示BRep的形狀中,參數表示的幾何曲面并不會孤立存在,他總是依附于拓樸面中。在OpenCascade的BRep格式的文件中三維幾何曲面共有十一種,通過將這十一種幾何曲面輸出,理解參數表示的幾何曲面的數據結構。

通過查看其讀寫幾何曲面的源程序,提出重構的方法。當在面向對象的程序中出現很條件表達式時,那么程序就有“壞味道”了,需要進行重構改進。

六、參考資料 References

1. OpenCascade. BRep Format Description White Paper

2. Martin Fowler. Refactoring:Improving the Design of Existing Code. Addison-Wesley

3. Les Piegl, Wayne Tiller. The NURBS Book. Springer-Verlag

 

Feedback

# re: Geometry Surface of OpenCascade BRep  回復  更多評論   

2015-06-04 19:56 by zhx
你好,請教下。
用GCPnts_TangentialDeflection離散邊EDGE后,下面的程序中得到的aPoint不是之前邊上的點坐標是為什么呢?怎么能得到邊上點的原始坐標值呢?
for (Standard_Integer i = 1; i <= thePointsOnCurve.NbPoints(); ++i)
{
u = thePointsOnCurve.Parameter(i);
aPoint = thePointsOnCurve.Value(i);
}
非常感謝!

# re: Geometry Surface of OpenCascade BRep  回復  更多評論   

2015-06-04 19:57 by zhx
@zhx
不好意思,上面的回復針對您的那篇名為“Mesh Algorithm in OpenCascade”的文章。

# re: Geometry Surface of OpenCascade BRep  回復  更多評論   

2015-06-04 20:49 by eryar
@zhx
Hi zhx,

這些aPoint是邊上的點啊!

你的邊上點的原始坐標值是什么意思?

Best Regards,
Shing Liu

# re: Geometry Surface of OpenCascade BRep  回復  更多評論   

2015-06-05 10:47 by zhx
@eryar
您好:
aPoint = thePointsOnCurve.Value(i)中的aPoint確實是EDGE上點的坐標,昨天是我的邊信息獲取的有誤,謝謝你!
另外我有另一個問題想請假下您:
曲面上的曲線PCurve將開孔的參數統一到曲面的UV參數空間時,用以下函數能獲取曲線的參數范圍(theFirst, theLast);
gp_Pnt2d theUV;
Handle_Geom2d_Curve thePCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, theFirst, theLast);
theUV = thePCurve.Value(theFirst);
那么我想問下,怎么獲取到與曲面上與點theUV相對應的點信息呢?

# re: Geometry Surface of OpenCascade BRep  回復  更多評論   

2015-06-05 19:13 by eryar
@zhx
Hi zhx,

關于pcurve更多信息,可參考這兩篇blogs:
PCurve - Curve on Surface:
http://m.shnenglu.com/eryar/archive/2014/03/15/206180.html

OpenCASCADE PCurve of Topological Face:
http://m.shnenglu.com/eryar/archive/2015/04/25/210441.html
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久福利视频| 国产精品专区h在线观看| 亚洲国产免费| 暖暖成人免费视频| 久久影视精品| 女人色偷偷aa久久天堂| 嫩草国产精品入口| 欧美激情视频一区二区三区不卡| 免费视频亚洲| 亚洲人www| 最新国产乱人伦偷精品免费网站 | 欧美日韩亚洲一区| 欧美精品三区| 国产精品久久久久久av福利软件 | 日韩视频不卡中文| 亚洲影院免费| 快she精品国产999| 亚洲激情综合| 亚洲综合精品| 麻豆精品传媒视频| 欧美日韩亚洲一区二区三区在线| 国产欧美日韩三级| 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲婷婷免费| 老鸭窝亚洲一区二区三区| 亚洲国产成人久久综合| 中文高清一区| 欧美gay视频| 国产精品综合久久久| 91久久精品日日躁夜夜躁欧美 | 亚洲视频在线观看三级| 久久男人资源视频| 国产精品久久久久久影视| 一区二区视频免费在线观看| 中日韩美女免费视频网址在线观看| 久久成人久久爱| 亚洲精品永久免费| 久久天天躁狠狠躁夜夜av| 国产精品免费一区二区三区在线观看 | 国产在线观看一区| 9i看片成人免费高清| 久久一区视频| 亚洲欧美日韩一区| 欧美日韩福利视频| 亚洲国产99精品国自产| 欧美中文在线视频| 一区二区欧美日韩| 欧美日本韩国一区| 亚洲国产精品va在线看黑人| 久久久久免费| 香蕉久久一区二区不卡无毒影院| 午夜精品视频| 欧美在线综合视频| 一区二区三区日韩欧美精品| 嫩草国产精品入口| 精品69视频一区二区三区| 亚洲女人av| 亚洲色图自拍| 国产精品久久久久久久久久三级 | 亚洲乱码国产乱码精品精| 欧美77777| 久久久久久久欧美精品| 国产综合色产| 久久夜色精品| 久久久久久久久久久久久女国产乱| 国产亚洲精品bt天堂精选| 亚洲欧美日韩天堂| 亚洲一区二区三区四区视频| 国产精品久久久久国产精品日日| 亚洲欧美视频在线观看| 亚洲一区三区电影在线观看| 国产精品外国| 久久久99精品免费观看不卡| 欧美一区二区三区另类| 激情综合网址| 亚洲欧洲在线看| 欧美日韩精品在线播放| 亚洲一区二区成人在线观看| 亚洲无毛电影| 国产中文一区二区| 欧美激情1区| 欧美视频中文字幕| 久久国产精品久久久| 久久天天躁狠狠躁夜夜av| 一本色道久久| 新狼窝色av性久久久久久| 一区精品在线播放| 亚洲精品国精品久久99热一| 国产精品久久久久9999| 久久久久久久欧美精品| 欧美成年人视频网站欧美| 亚洲一二三四久久| 久久精品99久久香蕉国产色戒| 亚洲国产婷婷香蕉久久久久久99| 夜夜嗨av一区二区三区四区| 国内精品久久久久久影视8| 亚洲第一精品夜夜躁人人躁| 国产精品二区三区四区| 免费在线欧美视频| 国产精品欧美经典| 亚洲国产成人久久| 国产亚洲欧美在线| 日韩天堂av| 在线观看日韩www视频免费| av成人毛片| 最新高清无码专区| 香蕉视频成人在线观看| 一区电影在线观看| 麻豆精品精品国产自在97香蕉| 亚洲欧美日韩国产综合在线| 欧美成人69av| 久久久久国产一区二区三区四区 | 欧美理论大片| 欧美一区网站| 欧美日本韩国一区| 久久久噜噜噜久久中文字幕色伊伊| 欧美成人精精品一区二区频| 久久本道综合色狠狠五月| 欧美成人资源网| 老巨人导航500精品| 欧美特黄一区| 亚洲欧洲日本在线| 亚洲第一在线视频| 性欧美大战久久久久久久免费观看 | 亚洲欧美精品suv| aⅴ色国产欧美| 欧美a级一区二区| 欧美/亚洲一区| 尤物网精品视频| 久久精品一区二区三区四区| 久久国产免费看| 国产欧美欧美| 亚洲欧美精品在线| 亚洲欧美在线一区| 久久免费视频观看| 亚洲砖区区免费| 亚洲高清在线播放| 久久免费一区| 国产精品免费一区二区三区在线观看| 欧美激情 亚洲a∨综合| 黄色工厂这里只有精品| 中国成人亚色综合网站| 一本色道88久久加勒比精品 | 国产精品日韩在线播放| a91a精品视频在线观看| 在线亚洲伦理| 欧美香蕉大胸在线视频观看| 一区二区激情小说| 欧美一区二区成人| 国产在线欧美| 欧美成人免费在线观看| 亚洲精品免费一区二区三区| 一区二区三区四区精品| 国产精品剧情在线亚洲| 性欧美超级视频| 你懂的国产精品| 99精品热6080yy久久| 国产精品久久久久一区| 欧美一区二区三区四区在线观看 | 亚洲欧美日韩爽爽影院| 国产精品一区二区男女羞羞无遮挡| 亚洲欧美日韩视频一区| 美女黄色成人网| 99精品免费| 欧美区在线观看| 一区二区激情| 欧美激情第9页| 亚洲一区二区视频| 久久久久久久网站| 一本久久综合| 国产日韩欧美一区| 免费观看成人| 亚洲天堂av高清| 免费精品99久久国产综合精品| 亚洲美女在线看| 国产一区二区三区在线观看视频 | 久久久美女艺术照精彩视频福利播放| 欧美黑人国产人伦爽爽爽| 中国成人黄色视屏| 狠狠久久五月精品中文字幕| 欧美精品入口| 欧美在线观看网站| a4yy欧美一区二区三区| 免费观看亚洲视频大全| 亚洲丝袜av一区| 亚洲高清不卡| 国产欧美精品日韩区二区麻豆天美| 久久夜色精品国产欧美乱极品| 亚洲视频一区二区免费在线观看| 麻豆久久婷婷| 久久精品国产96久久久香蕉| 99在线精品视频| 激情欧美国产欧美| 国产精品久久久久久久久免费| 免费短视频成人日韩| 久久成人精品电影| 亚洲欧美日本视频在线观看| 亚洲人成网站在线观看播放| 欧美成人激情在线| 久久高清免费观看|