NX二次开发-判断相同零件

ug 二次开发相同实体判断: 

关键在于在两个体上找到唯一参考建立坐标

缺陷:1.没有平面的实体(解决方案:在体上找一条开口的非直边以固定比例取边上三点建立一个平面),2.平面上不存在开口的边,因为闭合边起点和终点位置不确定(解决方案方案:如果平面上存在圆弧边可以取最大圆弧边的中心点,和质心点在该平面的投影点作为建立唯一坐标的X轴参考方向),3如果这个零件即没有平面又没有开口边(??)
————————————————

                           

 
#ifndef SAME_BODY_TOOL1
#define SAME_BODY_TOOL1
#ifdef _MSC_VER
#pragma once
#endif #include <uf.h>
#include <atlstr.h>
#include <io.h>
#include <vector>
#include <sstream>
#include <iostream>
#include <map>
#include <uf_ui.h>
#include<uf_curve.h>
#include<NXOpen/DirectionCollection.hxx>
#include<NXOpen/MeasureManager.hxx>
#include "./jUnit.h"
namespace SBT {
 class BodyData;
 class FaceData;
 class DirectionData;
 class SameBodyTool;
 inline void  outMsg(double* arr, int size) {
  logical isOpen = false;
  UF_UI_is_listing_window_open(&isOpen);
  if (!isOpen)UF_UI_open_listing_window();
  for (int i = 0; i < size; i++) {
   char c[1000];
   sprintf(c, " %f,", arr[i]);
   UF_UI_write_listing_window(c);
  }
  UF_UI_write_listing_window("\n");
 }
 inline void  outMsg(std::vector<double> list, int size) {
  logical isOpen = false;
  UF_UI_is_listing_window_open(&isOpen);
  if (!isOpen)UF_UI_open_listing_window();
  for (int i = 0; i < size; i++) {
   char c[1000];
   sprintf(c, " %f,", list[i]);
   UF_UI_write_listing_window(c);
  }
  UF_UI_write_listing_window("\n");
 }
 inline void  outMsg(NXOpen::NXString str1, int n) {
  char c[256];
  sprintf(c, "%s : %d", str1.GetLocaleText(), n);
  UF_UI_open_listing_window();   UF_UI_write_listing_window(c);
  UF_UI_write_listing_window("\n");
 }
 inline void  outMsg(NXOpen::NXString str1,double n) {
  char c[256];
  sprintf(c, "%s : %f", str1.GetLocaleText(), n);
  UF_UI_open_listing_window();   UF_UI_write_listing_window(c);
  UF_UI_write_listing_window("\n");
 }
 inline void  outMsg(NXOpen::NXString str1, NXOpen::NXString str2) {
  ostringstream oss;
  oss << str1.GetLocaleText() << " : " << str2.GetLocaleText();
  UF_UI_open_listing_window();
  UF_UI_write_listing_window(oss.str().c_str());
  UF_UI_write_listing_window("\n");
 }
 inline int  getBodyMassCenter(tag_t bodyTag, double massCenter[3]) {   if (bodyTag) {
   double mtx[9] = { 1,0,0,0,1,0,0,0,1 };
   tag_t mtxTag = NULL_TAG;
   UF_CALL(UF_CSYS_create_matrix(mtx, &mtxTag));
   double origin[3] = { 0 };
   tag_t tempCsys = NULL_TAG;
   UF_CALL(UF_CSYS_create_temp_csys(origin, mtxTag, &tempCsys));
   UF_CALL(UF_CSYS_set_wcs(tempCsys));
   //
   int num_objs;
   int type = 1;
   int units;
   double density;
   int accuracy;
   double acc_value[11] = { 0.01,0,0,0,0,0,0,0,0,0,0 };
   double mass_props[47];
   double statistics[13];
   UF_MODL_ask_mass_props_3d(&bodyTag, 1, type, 3, 1.0, 1, acc_value, mass_props, statistics);
   massCenter[0] = mass_props[3] * 10;
   massCenter[1] = mass_props[4] * 10;
   massCenter[2] = mass_props[5] * 10;
   return 0;
  }
  return 1;
 }
 inline bool getTempCsys(double origin[3], double xDir[3],double yDir[3],tag_t &tempCsysTag, double originOut[3], double mtxOut[9]) {
  UF_VEC3_copy(origin, originOut);
  UF_CALL(UF_MTX3_initialize(xDir, yDir, mtxOut));
  tag_t mtxInTag = NULL_TAG;
  UF_CALL(UF_CSYS_create_matrix(mtxOut, &mtxInTag));
  if(!UF_CALL(UF_CSYS_create_temp_csys(origin, mtxInTag, &tempCsysTag))){
   return true;
  }
  return false;
 }
 inline bool getTempCsys(double origin[3], double xDir[3], double yDir[3]) {
  try
  {
   double mtxOut[9] = { 0 };
   UF_CALL(UF_MTX3_initialize(xDir, yDir, mtxOut));
   tag_t mtxInTag = NULL_TAG;
   tag_t tempCsysTag = NULL_TAG;
   UF_CALL(UF_CSYS_create_matrix(mtxOut, &mtxInTag));
   if (!UF_CALL(UF_CSYS_create_csys(origin, mtxInTag, &tempCsysTag))) {
    return true;
   }
  }
  catch (const std::exception& e)
  {
   outMsg("getTempCsys", e.what());
  }
  
  return false;
 }
 inline bool compCsys1(const tag_t& tempCsysTag, double massCneterWCS[3], double massCneterABS[3]) {
  double massCneterWCS2[3] = { 0 };
  UF_CALL(UF_CSYS_set_wcs(tempCsysTag));
  UF_CALL(UF_CSYS_map_point(UF_CSYS_ROOT_COORDS, massCneterABS, UF_CSYS_ROOT_WCS_COORDS, massCneterWCS2));
  double dist = 0;
  UF_VEC3_distance(massCneterWCS, massCneterWCS2, &dist);
  if (dist < 0.01) return true;
  return false;
 }
 inline void getBodyMassCenterWCS(Body* body, double originIn[3], double mtxIn1[9], double massCneterOut[3]) {
  tag_t tempCsys1 = NULL_TAG;
  double massCneter1[3] = { 0 };
  getTempCsys(originIn, mtxIn1, mtxIn1 + 3, tempCsys1, originIn, mtxIn1);
  getBodyMassCenter(body->Tag(), massCneter1);
  UF_CALL(UF_CSYS_set_wcs(tempCsys1));
  UF_CALL(UF_CSYS_map_point(UF_CSYS_ROOT_COORDS, massCneter1, UF_CSYS_ROOT_WCS_COORDS, massCneterOut));
 }
 inline bool findSameCsys(Body * body1,double originIn[3], double mtxIn1[9], Body* body2, double originIn2[3], double mtxIn2[9],double originOut[3],double mtxOut2[9] ) {
  try
  {
   if (body1 == NULL || body2 == NULL)return false;
   double massCneter1[3] = { 0 };
   getBodyMassCenterWCS(body1, originIn, mtxIn1, massCneter1);
   //
   {
    double massCneter2[3] = { 0 };
    getBodyMassCenter(body2->Tag(), massCneter2);
    tag_t tempCsys2 = NULL_TAG;
    getTempCsys(originIn2, mtxIn2, mtxIn2 + 3, tempCsys2, originOut, mtxOut2);
    if (compCsys1(tempCsys2, massCneter1, massCneter2)) return true;
    double  distances2[3];
    double  min_corner2[3];
    double  directions2[3][3];
    UF_CALL(UF_MODL_ask_bounding_box_exact(body2->Tag(), tempCsys2, min_corner2, directions2, distances2));
    outMsg("distances2[0]", distances2[0]);
    outMsg("distances2[1]", distances2[1]);
    outMsg("distances2[2]", distances2[2]);
    tag_t tempCsys1 = NULL_TAG;
    getTempCsys(originIn, mtxIn1, mtxIn1 + 3, tempCsys1, originOut, mtxOut2);
    double  distances1[3];
    double  min_corner1[3];
    double  directions1[3][3];
    UF_CALL(UF_MODL_ask_bounding_box_exact(body1->Tag(), tempCsys1, min_corner1, directions1, distances1));
    outMsg("distances1[0]", distances1[0]);
    outMsg("distances1[1]", distances1[1]);
    outMsg("distances1[2]", distances1[2]);
    /*TTool::errorMsg(mtxIn1, 9);
    TTool::errorMsg(mtxIn2, 9);*/
    /*outMsg(directions1[0], 3);
    outMsg(directions1[1], 3);
    outMsg(directions1[2], 3);*/
    /* 取原点*/
    double  magnitude = 0;
    UF_VEC3_unitize(directions2[0], 0.00254, &magnitude, directions2[0]);
    UF_VEC3_unitize(directions2[1], 0.00254, &magnitude, directions2[1]);
    UF_VEC3_unitize(directions2[2], 0.00254, &magnitude, directions2[2]);
    vector<double*> pointList;
    double bPt1[3] = { 0 };
    UF_VEC3_copy(min_corner2, bPt1);
    double tPt1[3] = { 0 };
    UF_VEC3_affine_comb(bPt1, distances2[2], directions2[2], tPt1);     double bPt2[3] = { 0 };
    UF_VEC3_affine_comb(bPt1, distances2[0], directions2[0], bPt2);
    double tPt2[3] = { 0 };
    UF_VEC3_affine_comb(bPt2, distances2[2], directions2[2], tPt2);     double bPt3[3] = { 0 };
    UF_VEC3_affine_comb(bPt1, distances2[1], directions2[1], bPt3);
    double tPt3[3] = { 0 };
    UF_VEC3_affine_comb(bPt3, distances2[2], directions2[2], tPt3);     double bPt4[3] = { 0 };
    UF_VEC3_affine_comb(bPt2, distances2[1], directions2[1], bPt4);
    double tPt4[3] = { 0 };
    UF_VEC3_affine_comb(bPt4, distances2[2], directions2[2], tPt4);     double bPt5[3] = { (bPt4[0] + bPt1[0]) / 2,(bPt4[1] + bPt1[1]) / 2,(bPt4[2] + bPt1[2]) / 2 };
    double tPt5[3] = { 0 };
    UF_VEC3_affine_comb(bPt5, distances2[2], directions2[2], tPt5);
    pointList.push_back(bPt1);
    pointList.push_back(tPt1);
    pointList.push_back(bPt2);
    pointList.push_back(tPt2);
    pointList.push_back(bPt3);
    pointList.push_back(tPt3);
    pointList.push_back(bPt4);
    pointList.push_back(tPt4);
    pointList.push_back(bPt5);
    pointList.push_back(tPt5);
         /* 取x y 轴向*/
    double xdir[3] = { 0 };
    double ydir[3] = { 0 };
    for (int i = 0; i < 3; i++) {
     /*outMsg("abs(distances1[0] - distances2[i]", abs(distances1[0] - distances2[i]));
     outMsg("abs(distances1[1] - distances2[i]", abs(distances1[1] - distances2[i]));*/
     if (abs(distances1[0] - distances2[i]) < 0.05) {//X
      UF_VEC3_copy(directions2[i], xdir);
      for (int j = 0;j < 3;j++) {
       if (j==i)continue;
       if (abs(distances1[1] - distances2[j]) < 0.05) {//Y
        UF_VEC3_copy(directions2[j], ydir);
        for (int k = 0; k < pointList.size(); k++) {
         /*tag_t pt = NULL_TAG;
         UF_CURVE_create_point(pointList[i],&pt);
         UF_OBJ_set_color(pt,186);*/
         tag_t tempCsys = NULL_TAG;
         double _xdir[3] = { 0 };
         double _ydir[3] = { 0 };
         UF_VEC3_negate(xdir, _xdir);
         UF_VEC3_negate(ydir, _ydir);
         if (getTempCsys(pointList[k], xdir, ydir, tempCsys, originOut, mtxOut2)) {
          if (compCsys1(tempCsys, massCneter1, massCneter2)) return true;
         }
         if (getTempCsys(pointList[k], _xdir, ydir, tempCsys, originOut, mtxOut2)) {
          if (compCsys1(tempCsys, massCneter1, massCneter2)) return true;
         }
         if (getTempCsys(pointList[k], xdir, _ydir, tempCsys, originOut, mtxOut2)) {
          if (compCsys1(tempCsys, massCneter1, massCneter2)) return true;
         }
         if (getTempCsys(pointList[k], _xdir, _ydir, tempCsys, originOut, mtxOut2)) {
          if (compCsys1(tempCsys, massCneter1, massCneter2)) return true;
         }
        }        }
      }
     }
    }
    
    
   }   }
  catch (const std::exception& e)
  {
   outMsg("findSameCsys",e.what());
  }
  
  return false;
  
 }
 inline int getAttrValueStr(tag_t objTag, NXOpen::NXString title1, std::string& valStr) {
  UF_ATTR_value_t val;
  valStr = "";
  if (objTag == NULL_TAG || strlen(title1.GetLocaleText()) < 1) {
   TTool::testUC("exception in method:JUnit::getAttrValueStr,objTag==NULL_TAG or title1 null");
   return 1;
  }
  char title[UF_ATTR_MAX_TITLE_LEN + 1] = "";
  sprintf_s(title, "%s", title1.GetLocaleText());
   val.value.string = NULL;
   UF_CALL(UF_ATTR_read_value(objTag, title, UF_ATTR_string, &val));
   if (val.type == UF_ATTR_string) {
    valStr = val.value.string;
    UF_free(val.value.string);
    return 0;
   }
  return 1;
 }
  //分割字符1
  inline std::vector<NXOpen::NXString>  splitStr(NXOpen::NXString str, NXOpen::NXString c) {
   //存放起始值和终止值
   std::vector<NXOpen::NXString> numberStrV;    //^两边数据代表起始值和末值
   char* pt = strtok(const_cast<char*>(str.GetLocaleText()), c.GetLocaleText());
   while (pt) {
    //TestUnit::outMsg(pt);
    numberStrV.push_back(pt);
    pt = strtok(NULL, c.GetLocaleText());
   }
   return numberStrV;
  }
  inline bool testGetData(tag_t bodyTag, double origin[3], double mtx[9]) {
  try
  {
   /*零点坐标*/
   std::string csysOrigin = "";
   if (getAttrValueStr(bodyTag, "CSYS_ORIGIN", csysOrigin))return false;
   std::vector<NXOpen::NXString >arrOrigin = splitStr(csysOrigin, ",");
   if (arrOrigin.size() == 3) {
    origin[0] = stod(arrOrigin[0].GetLocaleText());
    origin[1] = stod(arrOrigin[1].GetLocaleText());
    origin[2] = stod(arrOrigin[2].GetLocaleText());
   }
   std::string valMtx = "";
   if (getAttrValueStr(bodyTag,"VIEW_MTX", valMtx))return false;
   std::vector<NXOpen::NXString >arrMtx =  splitStr(valMtx, ",");
   if (arrMtx.size() == 9) {
    mtx[0] = stod(arrMtx[0].GetLocaleText());
    mtx[1] = stod(arrMtx[1].GetLocaleText());
    mtx[2] = stod(arrMtx[2].GetLocaleText());
    mtx[3] = stod(arrMtx[3].GetLocaleText());
    mtx[4] = stod(arrMtx[4].GetLocaleText());
    mtx[5] = stod(arrMtx[5].GetLocaleText());
    mtx[6] = stod(arrMtx[6].GetLocaleText());
    mtx[7] = stod(arrMtx[7].GetLocaleText());
    mtx[8] = stod(arrMtx[8].GetLocaleText());
   }
   
   UF_CALL(UF_MTX3_initialize(mtx, mtx + 3, mtx));
  }
  catch (const std::exception& e)
  {
   outMsg("findSameCsys",e.what());
   return false;
  }
  
  return true;
 }
 inline void test1(std::vector<TaggedObject*>& list) {
  if (list.size() > 1) {
   //TTool::errorMsg("=====================");
   Body* body1 = dynamic_cast<Body*>(list[0]);
   Body* body2 = dynamic_cast<Body*>(list[1]);
   double originOut[3] = { 0 };
   double mtxOut[9] = { 0 };
   double origin1[3] = { 0 };
   double mtx1[9] = { 0 };
   double origin2[3] = { 0 };
   double mtx2[9] = { 0 };
   testGetData(body1->Tag(), origin1, mtx1);
   //TTool::errorMsg(origin1,3);
   //TTool::errorMsg(mtx1,9);
   
   testGetData(body2->Tag(), origin2, mtx2);
   //TTool::errorMsg(origin2, 3);
   //TTool::errorMsg(mtx2, 9);
   if (findSameCsys(body1, origin1, mtx1, body2, origin2, mtx2, originOut, mtxOut)) {
    getTempCsys(originOut, mtxOut, mtxOut+3);
   };
   getTempCsys(origin1, mtx1, mtx1 + 3);   }
 }  inline bool isCloseEdge(tag_t edgeTag) {
  if (edgeTag) {
   double pt1[3] = { 0 };
   double pt2[3] = { 0 };
   int num = 0;
   UF_CALL(UF_MODL_ask_edge_verts(edgeTag, pt1, pt2, &num));
   if (num == 1) {
    UF_VEC3_copy(pt1, pt2);
   }
   double dist = 0;
   UF_VEC3_distance(pt1, pt2, &dist);
   if (dist < 0.01) return true;
  }
  return false;
 }
 inline bool isCloseEdgeFace(Face* face) {
  bool flag = true;
  uf_list_p_t edgeList = NULL;
  uf_list_p_t edgeList_ = NULL;
  UF_CALL(UF_MODL_ask_face_edges(face->Tag(), &edgeList));
  edgeList_ = edgeList;
  while (edgeList)
  {
   if (!isCloseEdge(edgeList->eid))
   {
    flag = false;
    break;
   }
   edgeList = edgeList->next;
  }
  UF_MODL_delete_list(&edgeList_);
  return flag;
 }
 inline void  setBodyColor(tag_t bodyTag, int color) {
  if (color < 1 || color>255 || bodyTag == NULL_TAG) return;
  Session* theSession = Session::GetSession();
  Part* workPart(theSession->Parts()->Work());
  Session::UndoMarkId markId1;
  markId1 = theSession->SetUndoMark(Session::MarkVisibilityVisible, "Edit Object Display");
  DisplayModification* displayModification1;
  displayModification1 = theSession->DisplayManager()->NewDisplayModification();  displayModification1->SetApplyToAllFaces(true);  displayModification1->SetApplyToOwningParts(false);  displayModification1->SetNewColor(color);  std::vector<DisplayableObject*> objects1(1);
  Body* body1(dynamic_cast<Body*>(NXObjectManager::Get(bodyTag)));
  if (body1) {
   objects1[0] = body1;
   displayModification1->Apply(objects1);
  }  delete displayModification1;
 }
 inline void  getFaceDir(tag_t faceTag, double dir[3]) {
  try
  {
   Session* theSession = Session::GetSession();
   Part* workPart(theSession->Parts()->Work());
   Face* face1 = dynamic_cast<Face*>(NXObjectManager::Get(faceTag));    Direction* direction1;
   direction1 = workPart->Directions()->CreateDirection(face1, SenseForward, SmartObject::UpdateOptionAfterModeling);
   Vector3d vec1 = direction1->Vector();
   dir[0] = vec1.X;
   dir[1] = vec1.Y;
   dir[2] = vec1.Z;
  }
  catch (const std::exception& e)
  {
   UF_OBJ_set_color(faceTag, 1);
   //TTool::testUC("exception in  getFaceDir", e.what());
  }  }
 /*获取圆弧边的中心 */
 inline int  getCycleEdgeCenter(tag_t edge1Tag, double center[3]) {
  if (!edge1Tag) return 1;
  double arc_length;
  UF_EVAL_p_t elpt;
  UF_EVAL_initialize(edge1Tag, &elpt);
  bool isArc;
  UF_EVAL_is_arc(elpt, &isArc);
  if (isArc == false)
  {
   UF_EVAL_free(elpt);
   return 1;
  }
  UF_EVAL_arc_t lat;
  UF_EVAL_ask_arc(elpt, &lat);
  UF_VEC3_copy(lat.center, center);
  UF_EVAL_free(elpt);
  return 0;
 }
 inline void  getPointOnEdge(tag_t edgeTag, double param, double outPoint[3]) {
  double tangent1[3] = { 0 };
  double p_norm1[3] = { 0 };
  double b_norm1[3] = { 0 };
  double torsion = 0;
  double rad_of_cur = 0;
  UF_MODL_ask_curve_props(edgeTag, param, outPoint, tangent1, p_norm1, b_norm1, &torsion, &rad_of_cur);
 }
 inline double getFaceArea(Face* face)
 {
  double area = 0;
  try
  {
   Session* theSession = Session::GetSession();
   Part* workPart(theSession->Parts()->Work());
   Part* displayPart(theSession->Parts()->Display());
   Unit* unit1(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("SquareMilliMeter")));
   Unit* unit2(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("MilliMeter")));
   vector<IParameterizedSurface*>object(1);
   object[0] = dynamic_cast<IParameterizedSurface*>(face);
   MeasureFaces* measureFaces1;
   measureFaces1 = workPart->MeasureManager()->NewFaceProperties(unit1, unit2, 0.9888, object);
   area = measureFaces1->Area();
   delete measureFaces1;   }
  catch (const std::exception& e)
  {
   outMsg("exception in method  getFaceArea", e.what());
  }
  return  area;
 }
 class DirectionData {
 public:
  Point3d p1;
  Point3d p2;
 };
 class FaceData
 {
 public:
  Face* face1;
  int status;
  //std::vector<Edge*> lessEdge;
  std::vector<DirectionData> dirList;
  int area;
  int lineEdgeLen;
 public:
  FaceData(Face* face, int area,bool isClose=false)
  {
   this->face1 = face;
   this->status = 0;
   this->area = area;
   this->lineEdgeLen = 0;    std::vector<Edge*> edgeList = face->GetEdges();
   std::map<int, std::vector<DirectionData>>lenAndDirList;
   if (isClose) {/*闭合*/
    for (int i = 0; i < edgeList.size(); i++) {
     Edge* edge1 = edgeList[i];
     if (edge1->SolidEdgeType() == Edge::EdgeTypeCircular) {
      double center1[3] = { 0 };
      JUnit::getCycleEdgeCenter(edge1->Tag(), center1);
      DirectionData dirData;
      dirData.p1 = Point3d(center1[0], center1[1], center1[2]);
      for (int j = 0; j < edgeList.size(); j++) {
       if (j == i)continue;
       Edge* edge2 = edgeList[j];
       if (edge2->SolidEdgeType() == Edge::EdgeTypeCircular) {
        double center2[3] = { 0 };
        JUnit::getCycleEdgeCenter(edge2->Tag(), center2);
        dirData.p2 = Point3d(center2[0], center2[1], center2[2]);
        double  dist = 0;
        UF_VEC3_distance(center1, center2, &dist);
        if (dist < 0.01)continue;
        int len = int(dist*1000.0);
        bool flag = true;
        for (auto it = lenAndDirList.begin(); it != lenAndDirList.end(); it++) {
         if (abs(it->first - len) < 10) {
          it->second.push_back(dirData);
          flag = false;
          break;
         }
        }
        if (flag)lenAndDirList[len].push_back(dirData);
       }       }
      break;
     }
    }
    if (lenAndDirList.empty()) {
     for (int i = 0; i < edgeList.size(); i++) {
      Edge* edge1 = edgeList[i];
      int len = (int)(edge1->GetLength() * 1000.0);
      DirectionData dirData;
      double pt1[3] = {0};
      double pt2[3] = {0};
      JUnit::getEdgeMidPoint(edge1->Tag(),0, pt1);
      JUnit::getEdgeMidPoint(edge1->Tag(),0.5, pt2);
      dirData.p1 = Point3d(pt1[0],pt1[1],pt1[2]);
      dirData.p2 = Point3d(pt2[0], pt2[1], pt2[2]);
      bool flag = true;
      for (auto it = lenAndDirList.begin(); it != lenAndDirList.end(); it++) {
       if (abs(it->first - len) < 10) {
        it->second.push_back(dirData);
        flag = false;
        break;
       }
      }
      if (flag)lenAndDirList[len].push_back(dirData);
     }
    }
   }
   else {/*开口*/
    for (int i = 0; i < edgeList.size(); i++) {
     Edge* edge1 = edgeList[i];
     int len = (int)(edge1->GetLength() * 1000.0);
     DirectionData dirData;
     edge1->GetVertices(&(dirData.p1), &(dirData.p2));
     bool flag = true;
     if (!SBT::isCloseEdge(edge1->Tag())) {
      for (auto it = lenAndDirList.begin(); it != lenAndDirList.end(); it++) {
       if (abs(it->first - len) < 10) {
        
        it->second.push_back(dirData);
        flag = false;
        break;
       }
      }
      if (flag)lenAndDirList[len].push_back(dirData);
     }
    }
   }
   if (lenAndDirList.size()) {
    size_t cout = 9999;
    for (auto it = lenAndDirList.begin(); it != lenAndDirList.end(); it++) {
     if (it->second.size() && it->second.size() < cout) {
      cout = it->second.size();
      this->dirList = it->second;
      this->lineEdgeLen = it->first;
     }
     else if (it->second.size() && it->second.size() == cout) {
      if (it->first > this->lineEdgeLen) {
       this->dirList = it->second;
       this->lineEdgeLen = it->first;
      }
     }
    }    }
   if (this->face1 != NULL && this->lineEdgeLen > 0 && this->dirList.size())this->status = 1;
  }   ~FaceData() {};  };
 class BodyData {
 public:
  Body* body1;
  int status;
  std::vector<FaceData> lessFaces;
  std::vector<std::vector<double>> pointsList;
  std::vector<std::vector<double>> pointsListWCS;
  int lessFaceArea;
  double standMtx[9];
 public:
  BodyData(Body* body) {
   this->body1 = body;
   this->lessFaceArea = 0;
   this->status = 0;
   std::vector<Face* >facelist = body->GetFaces();
   std::map<int, std::vector<Face*>> areaAndPlanarFacesOpen;
   std::map<int, std::vector<Face*>> areaAndPlanarFacesClose;        for (int i = 0; i < facelist.size(); i++) {
    Face* face1 = facelist[i];
    
    if (face1->SolidFaceType() == Face::FaceTypePlanar) {      if (isCloseEdgeFace(face1)) {
      int area = (int)(getFaceArea(face1) * 1000.0);
      bool flag = true;
      for (auto it = areaAndPlanarFacesClose.begin(); it != areaAndPlanarFacesClose.end(); it++) {
       if (abs(it->first - area) < 8) {
        flag = false;
        it->second.push_back(face1);
        break;
       }
      }
      if (flag)areaAndPlanarFacesClose[area].push_back(face1);
     }
     else {
      int area = (int)(getFaceArea(face1) * 1000.0);
      bool flag = true;
      for (auto it = areaAndPlanarFacesOpen.begin(); it != areaAndPlanarFacesOpen.end(); it++) {
       if (abs(it->first - area) < 8) {
        flag = false;
        it->second.push_back(face1);
        break;
       }
      }
      if (flag)areaAndPlanarFacesOpen[area].push_back(face1);
     }      
    }
   }
   
   if (areaAndPlanarFacesOpen.size()) {
    std::vector<Face*> tempList;
    size_t num = 9999;
    for (auto it = areaAndPlanarFacesOpen.begin(); it != areaAndPlanarFacesOpen.end(); it++) {
     if (it->second.size() && it->second.size() < num) {
      num = it->second.size();
      tempList = it->second;
      this->lessFaceArea = it->first;
     }
     else if (it->second.size() && it->second.size() == num) {
      if (it->first > this->lessFaceArea) {
       this->lessFaceArea = it->first;
       tempList = it->second;
      }
     }
    }
    for (int i = 0; i < tempList.size(); i++) {
     this->lessFaces.push_back(FaceData(tempList[i], this->lessFaceArea));
    }
   }
   else {
    std::vector<Face*> tempList;
    size_t num = 9999;
    for (auto it = areaAndPlanarFacesClose.begin(); it != areaAndPlanarFacesClose.end(); it++) {
     if (it->second.size() && it->second.size() < num) {
      num = it->second.size();
      tempList = it->second;
      this->lessFaceArea = it->first;
     }
     else if (it->second.size() && it->second.size() == num) {
      if (it->first > this->lessFaceArea) {
       this->lessFaceArea = it->first;
       tempList = it->second;
      }
     }
    }
    for (int i = 0; i < tempList.size(); i++) {
     this->lessFaces.push_back(FaceData(tempList[i], this->lessFaceArea,true));
    }
   }
   
   /*取点*/
   {
    std::vector<double> v(3);
    double pt[3] = { 0 };
     getBodyMassCenter(body->Tag(), pt);
    v[0] = pt[0];
    v[1] = pt[1];
    v[2] = pt[2];
    this->pointsList.push_back(v);
    this->pointsListWCS.push_back(v);
   }
   for (int i = 0; i < this->lessFaces.size(); i++) {
    UF_OBJ_set_color(this->lessFaces[i].face1->Tag(), 1);
   }
   if (this->body1 != NULL && lessFaces.size()) this->status = 1;
   
  };
 public:  };
 class SameBodyTool {
 public:
  std::vector<tag_t> csysTempList;
 public:
  ~SameBodyTool() {
   for (int i = 0; i < csysTempList.size(); i++) {
    UF_OBJ_delete_object(csysTempList[i]);
   }
  };
 public:
  void test(std::vector<TaggedObject*> list) {
   if (list.size() > 1) {     Body* b1 = dynamic_cast<Body*>(list.front());
    std::vector<Body* >bodyList;
    for (int i = 0; i < list.size(); i++) {
     Body* body = dynamic_cast<Body*>(list[i]);
     if (body)bodyList.push_back(body);
    }
    SBT::SameBodyTool sbTool;
    std::vector<Body* >sameBodies;
    sbTool.getSameBodies(b1, bodyList, sameBodies);     for (int i = 0; i < sameBodies.size(); i++) {
      setBodyColor(sameBodies[i]->Tag(), 1);
    }    }
  }
  void test2(std::vector<TaggedObject*> list) {
   if (list.size() > 1) {     Body* b1 = dynamic_cast<Body*>(list.front());
    std::vector<Body* >bodyList;
    for (int i = 0; i < list.size(); i++) {
     Body* body = dynamic_cast<Body*>(list[i]);
     if (body)bodyList.push_back(body);
    }
    SBT::SameBodyTool sbTool;
    std::vector<std::vector<Body* >>sameBodies;
    sbTool.getSameBodies(bodyList, sameBodies);
    for (int i = 0; i < sameBodies.size(); i++) {
     for (int j = 0; j < sameBodies[i].size(); j++) {
      setBodyColor(sameBodies[i][j]->Tag(), i + 1);
     }
    }    }
  }
  int getSameBodies(const std::vector<Body*>& inputList, std::vector < std::vector<Body*>>& outputList) {
   int err = 0;
   try
   {     if (inputList.size()) {
     
     std::set<tag_t> tool;
     for (int i = 0; i < inputList.size(); i++) {
      
      Body* body1 = inputList[i];
      if (tool.count(body1->Tag()))continue;
      tool.insert(body1->Tag());
      SBT::BodyData data1(body1);
      std::vector<Body*> sameBodies;
      sameBodies.push_back(body1);
      for (int j = i + 1; j < inputList.size(); j++) {
       Body* body2 = inputList[j];
       if (tool.count(body2->Tag()))continue;
       tool.insert(body2->Tag());
       SBT::BodyData data2(body2);
       if (this->isSame(data1, data2)) {
        sameBodies.push_back(body2);
       }
      }
      outputList.push_back(sameBodies);
     }
    }
   }
   catch (const std::exception&)
   {
    throw;
    err = 1;
   }
   return err;
  }
  int getSameBodies(Body* body1, const std::vector<Body*>& inputList, std::vector<Body*>& outputList) {
   int err = 0;
   try
   {     if (inputList.size()) {
     SBT::BodyData data1(body1);
     for (int i = 0; i < inputList.size(); i++) {
      Body* body2 = inputList[i];
      SBT::BodyData data2(body2);
      if (body2->Tag() != body1->Tag() && this->isSame(data1, data2)) {
       outputList.push_back(body2);
      }
     }
    }
   }
   catch (const std::exception&)
   {
    throw;
    err = 1;
   }
   return err;
  }
  bool isSame(SBT::BodyData &data1, SBT::BodyData &data2) {
   if (data1.status == 0 || data2.status == 0) return this->cursoryCmp(data1.body1, data2.body1);
   outMsg("data1.lessFaceArea",data1.lessFaceArea);
   outMsg("data2.lessFaceArea",data2.lessFaceArea);
   outMsg("abs(data1.lessFaceArea - data2.lessFaceArea)", abs(data1.lessFaceArea - data2.lessFaceArea));
   if (abs(data1.lessFaceArea - data2.lessFaceArea) < 10) {
    std::vector<FaceData>& dataList1 = data1.lessFaces;
    std::vector<FaceData>& dataList2 = data2.lessFaces;
    if (dataList1.size() && dataList2.size()) {
     FaceData& faceData1 = dataList1.front();
     Face* face1 = faceData1.face1;
     int lineEdgeLen1 = faceData1.lineEdgeLen;
     std::vector<DirectionData> &dirList1 = faceData1.dirList;
     if (dirList1.size()) {
      DirectionData dirData1 = dirList1.front();
      std::vector<std::vector<double>> wcsPointList1;
      this->getTransPoints(face1, dirData1, data1);
      for (int i = 0; i < dataList2.size(); i++) {
       outMsg("lineEdgeLen1", lineEdgeLen1);
       outMsg("dataList2[i].lineEdgeLen", dataList2[i].lineEdgeLen);
       outMsg("abs(dataList2[i].lineEdgeLen - lineEdgeLen1)", abs(dataList2[i].lineEdgeLen - lineEdgeLen1));
       if (abs(dataList2[i].lineEdgeLen - lineEdgeLen1) < 10) {
        if (this->cmpPoints(data1, data2, dataList2[i])) {
         return true;
        }
        else if (this->cmpPoints_(data1, data2, dataList2[i])) {
         return true;
        };
       }
       else {
        /*outMsg("lineEdgeLen1",lineEdgeLen1);
        outMsg("dataList2[i].lineEdgeLen", dataList2[i].lineEdgeLen);
        outMsg("abs(dataList2[i].lineEdgeLen - lineEdgeLen1)", abs(dataList2[i].lineEdgeLen - lineEdgeLen1));*/
       }
      }
     }     }
   }
   else {
    for (int i = 0; i < data1.lessFaces.size(); i++) {
     UF_OBJ_set_color(data1.lessFaces[i].face1->Tag(), 186);
    }
   }
   return false;
  };
  bool cmpPoints_(SBT::BodyData data1, SBT::BodyData data2, SBT::FaceData& faceData) {
   Face* face1 = faceData.face1;
   std::vector<DirectionData>& dirList = faceData.dirList;
   bool result = true;
   for (int i = 0; i < dirList.size(); i++) {
    DirectionData& dirData = dirList[i];
    this->getTransPoints_(face1, dirData, data2);
    result = true;
    for (int j = 0; j < data1.pointsListWCS.size(); j++) {
     std::vector<double >& v1 = data1.pointsListWCS[j];
     bool flag = true;
     int minDist = 90000;
     double minV1[3] = { 0 };
     double minV2[3] = { 0 };
     int minIndex = 0;
     for (int k = 0; k < data2.pointsListWCS.size(); k++) {
      std::vector<double >& v2 = data2.pointsListWCS[k];
      double pt1[3] = { v1[0],v1[1],v1[2] };
      double pt2[3] = { v2[0],v2[1],v2[2] };
      
      double dist = 0;
      UF_VEC3_distance(pt1, pt2, &dist);
      if (dist < 0.0254) {
       flag = false;
       break;
      }
      if ((int)(dist * 1000) < minDist) {
       minDist = (int)(dist * 1000);
       UF_VEC3_copy(pt1, minV1);
       UF_VEC3_copy(pt2, minV2);
       minIndex = k;
      }
     }
     if (flag) {/*没有对应点*/
      result = false;
      tag_t ptTag = NULL_TAG;
      outMsg("===================error:",1);
      outMsg(minV1, 3);
      outMsg(minV2, 3);
      double pt1[3] = { data2.pointsList[minIndex][0],data2.pointsList[minIndex][1],data2.pointsList[minIndex][2] };
      double pt2[3] = { data1.pointsList[j][0],data1.pointsList[j][1],data1.pointsList[j][2] };
      outMsg("minDist:", minDist);
      outMsg(pt1, 3);
      outMsg(pt2, 3);
      UF_CURVE_create_point(pt1, &ptTag);
      UF_OBJ_set_color(ptTag, 186);
      UF_CURVE_create_point(pt2, &ptTag);
      UF_OBJ_set_color(ptTag, 186);
      break;
     }
    }
    if (result) {
     return true;
    }
   }
   return false;
  }
  bool cmpPoints(SBT::BodyData data1, SBT::BodyData data2, SBT::FaceData& faceData) {
   Face* face1 = faceData.face1;
   std::vector<DirectionData> &dirList = faceData.dirList;
   bool result = true;
   for (int i = 0; i < dirList.size(); i++) {
    DirectionData& dirData = dirList[i];
    this->getTransPoints(face1, dirData, data2);
    result = true;
    for (int j = 0; j < data1.pointsListWCS.size(); j++) {
     std::vector<double >& v1 = data1.pointsListWCS[j];
     bool flag = true;
     int minDist = 90000;
     double minV1[3] = { 0 };
     double minV2[3] = { 0 };
     double minDist0 = 0;
     int minIndex = 0;
     for (int k = 0; k < data2.pointsListWCS.size(); k++) {
      std::vector<double >& v2 = data2.pointsListWCS[k];
      int n1 = (int)(v1[0] * 1000);
      int n2 = (int)(v1[1] * 1000);
      int n3 = (int)(v1[2] * 1000);
      int m1 = (int)(v2[0] * 1000);
      int m2 = (int)(v2[1] * 1000);
      int m3 = (int)(v2[2] * 1000);
      double pt1[3] = { v1[0],v1[1],v1[2] };
      double pt2[3] = { v2[0],v2[1],v2[2] };       double dist = 0;
      UF_VEC3_distance(pt1, pt2, &dist);
      if (dist < 0.0254) {
       flag = false;
       break;
      
      }
      
      if ((int)(dist * 1000) < minDist) {
       minDist = (int)(dist * 1000);
       minDist0 = dist;
       UF_VEC3_copy(pt1, minV1);
       UF_VEC3_copy(pt2, minV2);
       minIndex = k;
      }
     }
     if (flag) {/*没有对应点*/
      result = false;
      tag_t ptTag = NULL_TAG;
      outMsg("===================error:", 1);
      outMsg(minV1, 3);
      outMsg(minV2, 3);
      double pt1[3] = { data2.pointsList[minIndex][0],data2.pointsList[minIndex][1],data2.pointsList[minIndex][2] };
      double pt2[3] = { data1.pointsList[j][0],data1.pointsList[j][1],data1.pointsList[j][2] };
      outMsg("minDist0:", minDist0);
      outMsg("minDist:", minDist);
      outMsg(pt1, 3);
      outMsg(pt2, 3);
      UF_CURVE_create_point(pt1, &ptTag);
      UF_OBJ_set_color(ptTag, 186);
      UF_CURVE_create_point(pt2, &ptTag);
      UF_OBJ_set_color(ptTag, 186);
      break;
     }
    }
    if (result) {
     return true;
    }
   }    return false;
  }
  int  getTransPoints_(Face* face1, DirectionData& dirData, SBT::BodyData& data) {
   try
   {
    csysTempList.clear();
    double yDir[3] = { 0 };
    getFaceDir(face1->Tag(), yDir);
    bool flag = false;
    double p1[3] = { dirData.p1.X,dirData.p1.Y,dirData.p1.Z };
    double p2[3] = { dirData.p2.X,dirData.p2.Y,dirData.p2.Z };
    double xDir[3] = { 0 };
    UF_VEC3_sub(p1, p2, xDir);     double mtx[9] = { 0 };
    UF_MTX3_initialize(xDir, yDir, mtx);
    {
     UF_MTX3_copy(mtx, data.standMtx);
     tag_t mtxTag = NULL_TAG;
     tag_t csysTag = NULL_TAG;
     UF_CSYS_create_matrix(mtx, &mtxTag);
     UF_CSYS_create_csys(p1, mtxTag, &csysTag);
     csysTempList.push_back(csysTag);
     UF_CSYS_set_wcs(csysTag);
     for (int i = 0; i < data.pointsList.size(); i++) {
      double pt1[3] = { data.pointsList[i][0],data.pointsList[i][1],data.pointsList[i][2] };
      double pt2[3] = { 0 };
      UF_CSYS_map_point(UF_CSYS_ROOT_COORDS, pt1, UF_CSYS_ROOT_WCS_COORDS, pt2);
      data.pointsListWCS[i][0] = pt2[0];
      data.pointsListWCS[i][1] = pt2[1];
      data.pointsListWCS[i][2] = pt2[2];
     }
    }    }
   catch (const std::exception& e)
   {
    outMsg("exception in getTransPoints: ",e.what());
    return 1;
   }    return 0;
  }
  int  getTransPoints(Face* face1, DirectionData& dirData, SBT::BodyData& data) {
   try
   {
    csysTempList.clear();
    double yDir[3] = { 0 };
    getFaceDir(face1->Tag(), yDir);
    bool flag = false;
    double p1[3] = { dirData.p1.X,dirData.p1.Y,dirData.p1.Z };
    double p2[3] = { dirData.p2.X,dirData.p2.Y,dirData.p2.Z };
    double xDir[3] = { 0 };
    UF_VEC3_sub(p2, p1, xDir);     double mtx[9] = { 0 };
    UF_MTX3_initialize(xDir, yDir, mtx);
    {
     tag_t mtxTag = NULL_TAG;
     tag_t csysTag = NULL_TAG;
     UF_CSYS_create_matrix(mtx, &mtxTag);
     UF_CSYS_create_csys(p1, mtxTag, &csysTag);
     csysTempList.push_back(csysTag);
     UF_CSYS_set_wcs(csysTag);
     for (int i = 0; i < data.pointsList.size(); i++) {
      double pt1[3] = { data.pointsList[i][0],data.pointsList[i][1],data.pointsList[i][2] };
      double pt2[3] = { 0 };
      UF_CSYS_map_point(UF_CSYS_ROOT_COORDS, pt1, UF_CSYS_ROOT_WCS_COORDS, pt2);
      data.pointsListWCS[i][0] = pt2[0];
      data.pointsListWCS[i][1] = pt2[1];
      data.pointsListWCS[i][2] = pt2[2];
     }
    }
    
   }
   catch (const std::exception& e)
   {
    outMsg("exception in getTransPoints: ",e.what());
    return 1;
   }    return 0;
  }
  /*static void getEdgeVec(FaceData& data) {    for (int i = 0; i < data.dirList.size(); i++) {
    double p1[3] = { 0 };
    double p2[3] = { 0 };
    getPointOnEdge(data.lessEdge[i]->Tag(), 0, p1);
    getPointOnEdge(data.lessEdge[i]->Tag(), 0.5, p2);
    tag_t pTag1 = NULL_TAG;
    tag_t pTag2 = NULL_TAG;
    UF_CURVE_create_point(p1, &pTag1);
    UF_CURVE_create_point(p2, &pTag2);
    UF_OBJ_set_color(pTag1, 29);
    UF_OBJ_set_color(pTag2, 186);
   }
  }*/
  void getBodyData(tag_t bodyTag, double& mass, double& volume, double& area) {
   try
   {
    Session* theSession = Session::GetSession();
    Part* workPart(theSession->Parts()->Work());
    Part* displayPart(theSession->Parts()->Display());     std::vector<NXOpen::IBody*> objects;/** Array of solid bodies */     NXOpen::Body* body1 = dynamic_cast<NXOpen::Body*>(NXObjectManager::Get(bodyTag));
    objects.push_back(body1);     std::vector<Unit*> massUnits1(5);
    Unit* unit1(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("SquareMilliMeter")));
    massUnits1[0] = unit1;
    Unit* unit2(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("CubicMilliMeter")));
    massUnits1[1] = unit2;
    Unit* unit3(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("Kilogram")));
    massUnits1[2] = unit3;
    Unit* unit4(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("MilliMeter")));
    massUnits1[3] = unit4;
    Unit* unit5(dynamic_cast<Unit*>(workPart->UnitCollection()->FindObject("Newton")));
    massUnits1[4] = unit5;
    MeasureBodies* measureBodies1;
    measureBodies1 = workPart->MeasureManager()->NewMassProperties(massUnits1, 0.99, objects);
    NXObject* nullNXObject(NULL);
    MeasureBodyBuilder* measureBodyBuilder1;
    measureBodyBuilder1 = workPart->MeasureManager()->CreateMeasureBodyBuilder(nullNXObject);
    mass = measureBodies1->Mass();
    volume = measureBodies1->Volume();
    area = measureBodies1->Area();
    delete measureBodies1;    }
   catch (const std::exception& e)
   {
    TTool::testMsg("exception int getBodyData:", e.what());
   }
  }
  bool cursoryCmp(Body* body1, Body* body2) {
   //outMsg("cursoryCmp========================",1);
   if (body1==NULL||body2==NULL)return false;
   int faceSize = body1->GetFaces().size();
   
   if (body1->GetFaces().size() != faceSize) return false;
   int edgeSize = body1->GetEdges().size();
   if (body1->GetEdges().size() != edgeSize)return false;    double mass = 0;
   double volume = 0;
   double area = 0;
   this->getBodyData(body1->Tag(), mass, volume, area);    double mass1 = 0;
   double volume1 = 0;
   double area1 = 0;
   this->getBodyData(body2->Tag(), mass1, volume1, area1);
   if (abs(mass1 - mass) > 0.1|| abs(volume1 - volume) > 9 || abs(area1 - area) > 0.1) return false;
  }
 };
}
#endif;

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/m0_64802729/article/details/136340889

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值