Browse Source

初步完成物件相交测试API

蘭雅sRGB 3 weeks ago
parent
commit
3ec85037c4
3 changed files with 180 additions and 105 deletions
  1. 165 101
      cdrapp.cpp
  2. 11 0
      cdrapp.h
  3. 4 4
      main.cpp

+ 165 - 101
cdrapp.cpp

@@ -2,135 +2,199 @@
 #include <stdio.h>
 
 #define _USE_MATH_DEFINES
-#include <math.h>  //  C++ 在 math.h 中定义 M_PI 需要 _USE_MATH_DEFINES 宏
-
-bool Test_Intersect(corel* cdr){
-    cdr->ActiveDocument->Unit = cdrInch;
-    IVGShapePtr s[3];
-    IVGShapePtr si[3];
-    IVGShapePtr sm;
-    double x, y, radius = 1.5 ;
-    int r, g, b;
-
-    // 通过将 i 乘以 2.09439507 (120度的弧度),可以将三个椭圆均匀地分布在一个圆上。  
-    // radius = 1.5 则是决定椭圆的大小。 这个数字控制椭圆的半径,也就是椭圆的大小。 // 创建3个椭圆, 填色 RGB:  
-    for (int i = 0; i != 3; i++) {
-        x = cdr->ActivePage->SizeWidth / 2 + 1 * cos(i * M_PI * 2.0 / 3.0);
-        y = cdr->ActivePage->SizeHeight / 2 + 1 * sin(i * M_PI * 2.0 / 3.0);
-        s[i] = MakeEllipse(cdr, x, y, radius);
-        r = 255 * (i == 0);
-        g = 255 * (i == 1);
-        b = 255 * (i == 2);
-        s[i]->Fill->UniformColor->RGBAssign(r, g, b);
-    }
+#include <math.h> //  C++ 在 math.h 中定义 M_PI 需要 _USE_MATH_DEFINES 宏
 
-//  创建3个相交物件,   IVGShape::Intersect 函数原型
-//  IVGShapePtr IVGShape::Intersect ( struct IVGShape * TargetShape, VARIANT_BOOL LeaveSource, VARIANT_BOOL LeaveTarget );
-    for (int i = 0; i != 3; i++) {
-        int n = (i + 1) % 3;
-        si[i] = s[i]->Intersect(s[n], true, true);
-        auto c1 = s[i]->Fill->UniformColor;
-        auto c2 = s[n]->Fill->UniformColor;
-        r = c1->RGBRed + c2->RGBRed;
-        g = c1->RGBGreen + c2->RGBGreen;
-        b = c1->RGBBlue + c2->RGBBlue;
-        si[i]->Fill->UniformColor->RGBAssign(r, g, b);
+bool isDPCurve(IVGShapePtr s) {
+  auto dpc = (s->Type == cdrRectangleShape) || (s->Type == cdrEllipseShape) ||
+             (s->Type == cdrCurveShape) || (s->Type == cdrPolygonShape) ||
+             (s->Type == cdrBitmapShape);
+  return dpc;
+}
+IVGShapePtr CreateBoundary(corel *cdr, IVGShapePtr s) {
+  //  auto scp = s2->CreateBoundary(0, 0 , true, true);
+  //  这个 API X7 以上才支持,所以现在直接画矩形
+  BoundingBox box;
+  s->GET_BOUNDING_BOX(box);
+  auto scp =
+      cdr->ActiveLayer->CreateRectangle2(box.x, box.y, box.w, box.h, ZERO_4PC);
+  return scp;
+}
+// VGCore::IVGShapePtr VGCore::IVGShape::CreateBoundary ( double x, double y,
+// VARIANT_BOOL PlaceOnTop, VARIANT_BOOL DeleteSource ); VGCore::IVGShapePtr
+// VGCore::IVGShapeRange::CreateBoundary ( double x, double y, VARIANT_BOOL
+// PlaceOnTop, VARIANT_BOOL DeleteSource ); VARIANT_BOOL
+// VGCore::IVGCurve::IntersectsWith ( struct IVGCurve * Curve )
+void test_IntersectsWith(corel *cdr) {
+
+  auto sr = cdr->ActiveSelectionRange;
+  if (1 < sr->Count) {
+    bool isIn = false;
+
+    auto s1 = sr->Shapes->Item[1];
+    auto s2 = sr->Shapes->Item[2];
+
+    if (isDPCurve(s1) && isDPCurve(s2)) {
+      isIn = s1->GetDisplayCurve()->IntersectsWith(s2->GetDisplayCurve());
+    } else if (isDPCurve(s1)) {
+      // 群组文字和OLE等其他类型,创建一个临时边界范围
+      auto scp = CreateBoundary(cdr, s2);
+      isIn = s1->GetDisplayCurve()->IntersectsWith(scp->GetDisplayCurve());
+      scp->Delete();
+
+    } else if (isDPCurve(s2)) {
+      auto scp = CreateBoundary(cdr, s1);
+      isIn = scp->GetDisplayCurve()->IntersectsWith(s2->GetDisplayCurve());
+      scp->Delete();
+    } else {
+      auto scp = CreateBoundary(cdr, s1);
+      auto scp2 = CreateBoundary(cdr, s2);
+      isIn = scp->GetDisplayCurve()->IntersectsWith(scp2->GetDisplayCurve());
+      scp->Delete();
+      scp2->Delete();
     }
 
-   // 建立相交物件,填充白色
-   sm = si[1]->Intersect(si[2], true, true);
-   auto c3 = cdr->CreateRGBColor(255, 255, 255);
-   sm->Fill->UniformColor = c3;
-
-    return true;
+    if (isIn)
+      Test_Intersect(cdr);
+  }
 }
 
+bool Test_Intersect(corel *cdr) {
+  cdr->ActiveDocument->Unit = cdrInch;
+  IVGShapePtr s[3];
+  IVGShapePtr si[3];
+  IVGShapePtr sm;
+  double x, y, radius = 1.5;
+  int r, g, b;
+
+  // 通过将 i 乘以 2.09439507 (120度的弧度),可以将三个椭圆均匀地分布在一个圆上。
+  // radius = 1.5 则是决定椭圆的大小。 这个数字控制椭圆的半径,也就是椭圆的大小。
+  // // 创建3个椭圆, 填色 RGB:
+  for (int i = 0; i != 3; i++) {
+    x = cdr->ActivePage->SizeWidth / 2 + 1 * cos(i * M_PI * 2.0 / 3.0);
+    y = cdr->ActivePage->SizeHeight / 2 + 1 * sin(i * M_PI * 2.0 / 3.0);
+    s[i] = MakeEllipse(cdr, x, y, radius);
+    r = 255 * (i == 0);
+    g = 255 * (i == 1);
+    b = 255 * (i == 2);
+    s[i]->Fill->UniformColor->RGBAssign(r, g, b);
+  }
+
+  //  创建3个相交物件,   IVGShape::Intersect 函数原型
+  //  IVGShapePtr IVGShape::Intersect ( struct IVGShape * TargetShape,
+  //  VARIANT_BOOL LeaveSource, VARIANT_BOOL LeaveTarget );
+  for (int i = 0; i != 3; i++) {
+    int n = (i + 1) % 3;
+    si[i] = s[i]->Intersect(s[n], true, true);
+    auto c1 = s[i]->Fill->UniformColor;
+    auto c2 = s[n]->Fill->UniformColor;
+    r = c1->RGBRed + c2->RGBRed;
+    g = c1->RGBGreen + c2->RGBGreen;
+    b = c1->RGBBlue + c2->RGBBlue;
+    si[i]->Fill->UniformColor->RGBAssign(r, g, b);
+  }
+
+  // 建立相交物件,填充白色
+  sm = si[1]->Intersect(si[2], true, true);
+  auto c3 = cdr->CreateRGBColor(255, 255, 255);
+  sm->Fill->UniformColor = c3;
+
+  return true;
+}
 
+bool polygon_gravity_dot(corel *cdr) {
+  cdr->ActiveDocument->Unit = cdrMillimeter;
+  double x, y;
 
-bool polygon_gravity_dot(corel* cdr){
-    cdr->ActiveDocument->Unit = cdrMillimeter;
-    double x, y;
-
-//  IVGShapePtr ActiveShape;    // 获取当前选中的图形 函数原型
-    auto s = cdr->ActiveShape;
+  //  IVGShapePtr ActiveShape;    // 获取当前选中的图形 函数原型
+  auto s = cdr->ActiveShape;
 
-//  IVGShapeRangePtr IVGApplication::CreateShapeRange ( );
-    auto srs = cdr->CreateShapeRange();
+  //  IVGShapeRangePtr IVGApplication::CreateShapeRange ( );
+  auto srs = cdr->CreateShapeRange();
 
-//  获取节点函数原型
-//  IVGNodePtr IVGNodes::GetItem ( long Index );
-//  IVGNodePtr IVGNodeRange::GetItem ( long Index );
+  //  获取节点函数原型
+  //  IVGNodePtr IVGNodes::GetItem ( long Index );
+  //  IVGNodePtr IVGNodeRange::GetItem ( long Index );
 
-    for(auto i = 0; i < s->DisplayCurve->Nodes->Count; i++){
-        auto n = s->DisplayCurve->Nodes->Item[i+1];   
+  for (auto i = 0; i < s->DisplayCurve->Nodes->Count; i++) {
+    auto n = s->DisplayCurve->Nodes->Item[i + 1];
 
-        x = n->PositionX;  
-        y = n->PositionY;
-        printf("%f, %f\n", x, y);
+    x = n->PositionX;
+    y = n->PositionY;
+    printf("%f, %f\n", x, y);
 
-        // auto sy = MakeEllipse(cdr, x, y, 5); 
-        // sy->Outline->Color->RGBAssign(255, 0, 0);
+    // auto sy = MakeEllipse(cdr, x, y, 5);
+    // sy->Outline->Color->RGBAssign(255, 0, 0);
 
-        // auto sj = MakeRectangle(cdr, x, y, 10, 10); 
-        // sj->Outline->Color->RGBAssign(0, 255, 0);
+    // auto sj = MakeRectangle(cdr, x, y, 10, 10);
+    // sj->Outline->Color->RGBAssign(0, 255, 0);
 
-        auto l = DrawLine(cdr, x, y, s->CenterX, s->CenterY);
-        srs->Add(l);
-    }
+    auto l = DrawLine(cdr, x, y, s->CenterX, s->CenterY);
+    srs->Add(l);
+  }
 
-// HRESULT IVGShapeRange::CreateSelection ( );
-    srs->CreateSelection();
+  // HRESULT IVGShapeRange::CreateSelection ( );
+  srs->CreateSelection();
 
-    return true;
+  return true;
 }
 
 //  建立矩形和圆形函数原型
-//  IVGShapePtr IVGLayer::CreateRectangle2 ( double x, double y, double Width, double Height, 
-//                      double RadiusUL, double RadiusUR, double RadiusLR, double RadiusLL );
-
-//  IVGShapePtr IVGLayer::CreateEllipse2 ( double CenterX, double CenterY, double Radius1, 
-//                   double Radius2, double StartAngle, double EndAngle, VARIANT_BOOL Pie );
-IVGShapePtr MakeEllipse(corel* cdr, double x, double y, double r){
-    return  cdr->ActiveLayer->CreateEllipse2(x, y, r, ZERO_4PC); 
+//  IVGShapePtr IVGLayer::CreateRectangle2 ( double x, double y, double Width,
+//  double Height,
+//                      double RadiusUL, double RadiusUR, double RadiusLR,
+//                      double RadiusLL );
+
+//  IVGShapePtr IVGLayer::CreateEllipse2 ( double CenterX, double CenterY,
+//  double Radius1,
+//                   double Radius2, double StartAngle, double EndAngle,
+//                   VARIANT_BOOL Pie );
+IVGShapePtr MakeEllipse(corel *cdr, double x, double y, double r) {
+  return cdr->ActiveLayer->CreateEllipse2(x, y, r, ZERO_4PC);
 }
 
-IVGShapePtr MakeEllipse(corel* cdr, IVGShapePtr s, double r){
-    double x, y;
-    x = s->CenterX;  
-    y = s->CenterY;
-    return  cdr->ActiveLayer->CreateEllipse2(x, y, r, ZERO_4PC);   
+IVGShapePtr MakeEllipse(corel *cdr, IVGShapePtr s, double r) {
+  double x, y;
+  x = s->CenterX;
+  y = s->CenterY;
+  return cdr->ActiveLayer->CreateEllipse2(x, y, r, ZERO_4PC);
 }
 
-IVGShapePtr MakeRectangle(corel* cdr, double x, double y, double w, double h){
-    auto sj = cdr->ActiveLayer->CreateRectangle2(x, y, w, h, ZERO_4PC); 
-    sj->PutCenterX(x);
-    sj->PutCenterY(y);
-    return  sj;
+IVGShapePtr MakeRectangle(corel *cdr, double x, double y, double w, double h) {
+  auto sj = cdr->ActiveLayer->CreateRectangle2(x, y, w, h, ZERO_4PC);
+  sj->PutCenterX(x);
+  sj->PutCenterY(y);
+  return sj;
 }
 
-IVGShapePtr MakeRectangle(corel* cdr, IVGShapePtr s, double w, double h){
-    double x, y;
-    x = s->CenterX;  
-    y = s->CenterY;
-    auto sj = cdr->ActiveLayer->CreateRectangle2(x, y, w, h, ZERO_4PC); 
-    sj->PutCenterX(x);
-    sj->PutCenterY(y);
-    return  sj;
+IVGShapePtr MakeRectangle(corel *cdr, IVGShapePtr s, double w, double h) {
+  double x, y;
+  x = s->CenterX;
+  y = s->CenterY;
+  auto sj = cdr->ActiveLayer->CreateRectangle2(x, y, w, h, ZERO_4PC);
+  sj->PutCenterX(x);
+  sj->PutCenterY(y);
+  return sj;
 }
 
-
-// IVGShapePtr IVGLayer::CreateLineSegment ( double StartX, double StartY, double EndX, double EndY );
-// 画一条线,设置轮廓色 M100
-IVGShapePtr DrawLine(corel* cdr, double x1, double y1, double x2, double y2){
-    auto line = cdr->ActiveLayer->CreateLineSegment(x1, y1, x2, y2);
-    line->Outline->Color->CMYKAssign(0, 100, 0, 0);
-    return line;
+// IVGShapePtr IVGLayer::CreateLineSegment ( double StartX, double StartY,
+// double EndX, double EndY ); 画一条线,设置轮廓色 M100
+IVGShapePtr DrawLine(corel *cdr, double x1, double y1, double x2, double y2) {
+  auto line = cdr->ActiveLayer->CreateLineSegment(x1, y1, x2, y2);
+  line->Outline->Color->CMYKAssign(0, 100, 0, 0);
+  return line;
 }
 
-// IVGShapePtr IVGLayer::FindShape ( _bstr_t Name, enum cdrShapeType Type, long StaticID, VARIANT_BOOL Recursive );
+// IVGShapePtr IVGLayer::FindShape ( _bstr_t Name, enum cdrShapeType Type, long
+// StaticID, VARIANT_BOOL Recursive );
 
-// IVGShapePtr IVGLayer::CreateCurveSegment ( double StartX, double StartY, double EndX, double EndY, double StartingControlPointLength, 
-//                                     double StartingControlPointAngle, double EndingControlPointLength, double EndingControlPointAngle );
+// IVGShapePtr IVGLayer::CreateCurveSegment ( double StartX, double StartY,
+// double EndX, double EndY, double StartingControlPointLength,
+//                                     double StartingControlPointAngle, double
+//                                     EndingControlPointLength, double
+//                                     EndingControlPointAngle );
 
-// IVGShapePtr IVGLayer::CreateCurveSegment2 ( double x1, double y1, double StartingControlPointX, double StartingControlPointY, 
-//                                         double EndingControlPointX, double EndingControlPointY, double x2, double y2 );
+// IVGShapePtr IVGLayer::CreateCurveSegment2 ( double x1, double y1, double
+// StartingControlPointX, double StartingControlPointY,
+//                                         double EndingControlPointX, double
+//                                         EndingControlPointY, double x2,
+//                                         double y2 );

+ 11 - 0
cdrapp.h

@@ -15,11 +15,22 @@ void Call_CorelDRAW();
 bool polygon_gravity_dot(corel* cdr);
 
 bool Test_Intersect(corel* cdr);
+void test_IntersectsWith(corel* cdr);
 
 
 // 重新包装 创建物件函数
 #define ZERO_4PC 0, 0, 0, 0
 
+#define GET_BOUNDING_BOX(box)                                                  \
+  GetBoundingBox(&(box).x, &(box).y, &(box).w, &(box).h, false)
+
+typedef struct {
+  double x; 
+  double y; 
+  double w; 
+  double h; 
+} BoundingBox;
+
 IVGShapePtr MakeEllipse(corel* cdr, double x, double y, double r);
 IVGShapePtr MakeEllipse(corel* cdr, IVGShapePtr s, double r);
 

+ 4 - 4
main.cpp

@@ -25,10 +25,10 @@ void Call_CorelDRAW() {
 
 
 
-  //  调用CDR功能, 计算多边形重心点
-  polygon_gravity_dot(cdr);
+  // //  调用CDR功能, 计算多边形重心点
+  // polygon_gravity_dot(cdr);
 
-  // 绘制 RGB 三原色,测试相交建立物件
-  Test_Intersect(cdr);
+  // // 绘制 RGB 三原色,测试相交建立物件
+  test_IntersectsWith(cdr);
 
 }