Browse Source

异形群组初步完成

蘭雅sRGB 2 weeks ago
parent
commit
a858327acd
2 changed files with 90 additions and 59 deletions
  1. 88 58
      cdrapp.cpp
  2. 2 1
      cdrapp.h

+ 88 - 58
cdrapp.cpp

@@ -4,6 +4,22 @@
 #define _USE_MATH_DEFINES
 #include <math.h> //  C++ 在 math.h 中定义 M_PI 需要 _USE_MATH_DEFINES 宏
 
+void BeginOpt(corel *cdr) {
+  auto name = _bstr_t("Undo");
+  cdr->EventsEnabled = false;
+  cdr->ActiveDocument->BeginCommandGroup(name);
+  cdr->ActiveDocument->Unit = cdrMillimeter;
+  cdr->Optimization = true;
+}
+
+void EndOpt(corel *cdr) {
+  cdr->EventsEnabled = true;
+  cdr->Optimization = false;
+  cdr->EventsEnabled = true;
+  cdr->ActiveDocument->ReferencePoint = cdrBottomLeft;
+  cdr->Application->Refresh();
+  cdr->ActiveDocument->EndCommandGroup();
+}
 bool isDPCurve(IVGShapePtr s) {
   auto dpc = (s->Type == cdrRectangleShape) || (s->Type == cdrEllipseShape) ||
              (s->Type == cdrCurveShape) || (s->Type == cdrPolygonShape) ||
@@ -11,92 +27,106 @@ bool isDPCurve(IVGShapePtr s) {
   return dpc;
 }
 IVGShapePtr CreateBoundary(corel *cdr, IVGShapePtr s) {
-  auto scp = s->CreateBoundary(0, 0 , true, false);
+  auto scp = s->CreateBoundary(0, 0, true, false);
 
   //  这个 API X7 以上才支持,所以现在直接画矩形
   // BoundingBox box;
   // s->GET_BOUNDING_BOX(box);
-  // auto scp = cdr->ActiveLayer->CreateRectangle2(box.x, box.y, box.w, box.h, ZERO_4PC);
+  // auto scp = cdr->ActiveLayer->CreateRectangle2(box.x, box.y, box.w, box.h,
+  // ZERO_4PC);
 
   return scp;
 }
 
 // 从矩形边界坐标 获得中心坐标
-void calculate_center(const BoundingBox *box, double *center_x, double *center_y) {
-    *center_x = box->x + (box->w / 2);
-    *center_y = box->y + (box->h / 2);
+void calculate_center(const BoundingBox *box, double *center_x,
+                      double *center_y) {
+  *center_x = box->x + (box->w / 2);
+  *center_y = box->y + (box->h / 2);
 }
 
-// VGCore::cdrPositionOfPointOverShape VGCore::IVGShape::IsOnShape ( double x, double y, double HotArea ); 
-// VGCore::cdrPositionOfPointOverShape VGCore::IVGCurve::IsOnCurve ( double x, double y, double HotArea );
+// VGCore::cdrPositionOfPointOverShape VGCore::IVGShape::IsOnShape ( double x,
+// double y, double HotArea ); VGCore::cdrPositionOfPointOverShape
+// VGCore::IVGCurve::IsOnCurve ( double x, double y, double HotArea );
+
+bool BoundaryGroup(corel *cdr, IVGShapeRange *sr, IVGShapeRange *srs) {
+
+  if (sr->Count < 2)
+    return false;
 
-void test_IsOnShape(corel *cdr){
-  cdr->ActiveDocument->Unit = cdrMillimeter;
   BoundingBox box;
-  double x, y, r = 0.2;
+  double x, y;
   int OnSh = 0;
-  auto sr = cdr->ActiveSelectionRange;
-  auto sbox = sr->CreateBoundary(0, 0, true, false);  // 建立异性边界物件
-  sbox->Fill->UniformColor ->RGBAssign(255, 0, 0);    // 填充红色
-
-  auto srgp = cdr->CreateShapeRange();
+  auto bounds = sr->CreateBoundary(0, 0, true, false); // 建立异性边界物件
+  bounds->Fill->UniformColor->RGBAssign(255, 0, 0);    // 填充红色
 
-  for (int i = 0; i < sr->Count; i++) {
-    auto sh = sr->Shapes->Item[i + 1];
-    sh->GET_BOUNDING_BOX(box);      // 获得物件矩形边界坐标
-    calculate_center(&box, &x, &y);  // 获得物件中心坐标
+  auto sbox = bounds->BreakApartEx(); // 把边界 拆分为多个边界 用来分组
 
-    OnSh = sbox->IsOnShape(x, y, 1);
+  auto srgp = cdr->CreateShapeRange();
 
-    printf("x:%0.2f y:%0.2f  -> %d\n", x , y, OnSh);
+  for (int k = 0; k < sbox->Count; k++) {
 
+    for (int i = 0; i < sr->Count; i++) {
+      auto sh = sr->Shapes->Item[i + 1];
+      sh->GET_BOUNDING_BOX(box);      // 获得物件矩形边界坐标
+      calculate_center(&box, &x, &y); // 获得物件中心坐标
+      OnSh = sbox->Shapes->Item[k + 1]->IsOnShape(x, y, -1);
 
-    if(OnSh){
-      srgp->Add(sh);
-      printf("物件ID %d 在范围内\n", i + 1);
-      cdr->ActiveLayer->CreateEllipse2(x, y, r*10, 0,0,0,0);
+      if (OnSh) {
+        srgp->Add(sh);
+      } else if (isIntWith(cdr, sbox->Shapes->Item[k + 1], sh)) {
+        srgp->Add(sh);
+      }
     }
+    // 从Range中移除已分组的图形
+    sr->RemoveRange(srgp);
+    srs->Add(srgp->Group());
+    srgp->RemoveAll();
   }
-  srgp->Group();
   sbox->Delete();
+  return true;
 }
 
+void test_IsOnShape(corel *cdr) {
+
+  BeginOpt(cdr);
 
-// 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();
-    }
+  auto srs = cdr->CreateShapeRange();
+
+  BoundaryGroup(cdr, sr, srs);
+  srs->CreateSelection();
+
+  EndOpt(cdr);
+}
 
-    if (isIn)
-      Test_Intersect(cdr);
+// 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 )
+bool isIntWith(corel *cdr, IVGShape *s1, IVGShape *s2) {
+  bool isIn = false;
+  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();
   }
+  return isIn;
 }
 
 bool Test_Intersect(corel *cdr) {

+ 2 - 1
cdrapp.h

@@ -15,9 +15,10 @@ void Call_CorelDRAW();
 bool polygon_gravity_dot(corel* cdr);
 
 bool Test_Intersect(corel* cdr);
-void test_IntersectsWith(corel* cdr);
 void test_IsOnShape(corel *cdr);
 
+bool isIntWith(corel *cdr, IVGShape* s1 , IVGShape* s2);
+
 // 重新包装 创建物件函数
 #define ZERO_4PC 0, 0, 0, 0