- UID
- 697431
- 积分
- 7
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2013-8-17
- 最后登录
- 1970-1-1
|
发表于 2013-11-27 23:00:12
|
显示全部楼层
本帖最后由 LoveArx 于 2016-11-27 13:00 编辑
[ 本帖最后由 LoveArx 于 2016-11-27 12:54 编辑 ]\n\n在楼主的代码基础上优化了一下,当1000*1000网格,即2002条图元相交,速度提升了差不多一半。代码如下:
 - struct IntersectOnCurve
- {
- AcGeDoubleArray IntersectParamat;
- };
- int doublecmp( const void *a , const void *b )
- {
- return *(double *)a > *(double *)b ? 1 : -1;
- }
- void WTUModifyEnt::IntersectBreakSS (ads_name ss,AcDbVoidPtrArray& curveSegments,ads_real rTol)
- {
- Acad::ErrorStatus es;
- ads_name e1;
- AcGePoint3dArray nPoints;
- AcGeTol tol;
- tol.setEqualPoint(rTol);
- tol.setEqualVector(rTol);
- if (!(nPoints.isEmpty()))
- {
- nPoints.setPhysicalLength(0);
- nPoints.setLogicalLength(0);
- }
- long len;
- acedSSLength(ss,&len);
- //实体个数小于两个,直接返回值
- if (len < 2)
- {
- if (len = 1)
- {
- AcDbEntity *pEnt;
- AcDbObjectId Id;
- acedSSName(ss,0,e1);
- acdbGetObjectId(Id,e1);
- es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
- if (es != Acad::eOk)
- {
- pEnt->close();
- }
- curveSegments.append(pEnt);
- pEnt->close();
- }
- return;
- }
- //将选择集实体转换到对象数组IdArray
- AcDbObjectIdArray IdArray;
- AcDbEntity *pEnt,*pEnt1;
- AcDbObjectId Id,Id1;
- AcDbCurve *pCurve,*pCurve1;
- for (long i =0;i < len;i++)
- {
- acedSSName(ss,i,e1);
- acdbGetObjectId(Id,e1);
- es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
- if (es != Acad::eOk)
- {
- pEnt->close();
- }
- pCurve = AcDbCurve::cast(pEnt);
- if (pCurve == NULL)
- {
- pEnt->close();
- continue;
- }
- IdArray.append(Id);
- pEnt->close();
- }
- //曲线总个数
- len = IdArray.length();
- //创建曲线的IntersectOnCurve结构数组,每个元素保存对应曲线上的交点Param,以AcGeDoubleArray保存
- IntersectOnCurve * intersectpt = new IntersectOnCurve[len];
- //初始化intersectpt
- for (long i = 0;i < len;i++)
- {
- if (!(intersectpt.IntersectParamat.isEmpty()))
- {
- intersectpt.IntersectParamat.setPhysicalLength(0);
- intersectpt.IntersectParamat.setLogicalLength(0);
- }
- }
- for (long i = 0;i < len-1;i++)
- {
- Id = IdArray.at(i);
- acdbOpenObject(pEnt,Id,AcDb::kForRead);
- pCurve = AcDbCurve::cast(pEnt);
- AcGePoint3d pstart0,pend0;
- pCurve->getStartPoint(pstart0);
- pCurve->getEndPoint(pend0);
- for (long j = i+1;j < len;j++)
- {
- Id1 = IdArray.at(j);
- acdbOpenObject(pEnt1,Id1,AcDb::kForRead);
- pCurve1 = AcDbCurve::cast(pEnt1);
- AcGePoint3dArray nPts;
- //计算交点
- pEnt->intersectWith(pEnt1,AcDb::kOnBothOperands,nPts);
- AcGePoint3d pstart1,pend1,pt;
- pCurve1->getStartPoint(pstart1);
- pCurve1->getEndPoint(pend1);
- for (int m = 0;m < nPts.length();m++)
- {
- pt = nPts[m];
- if (!(pstart0.isEqualTo(pt,tol) || pend0.isEqualTo(pt,tol)))
- {
- //交点添加到第i条曲线上
- double paramat;
- pCurve->getParamAtPoint(pt,paramat);
- intersectpt.IntersectParamat.append(paramat);
- }
- if (!(pstart1.isEqualTo(pt,tol) || pend1.isEqualTo(pt,tol)))
- {
- //交点添加到第j条曲线上
- //Pt3DArrays[j].append(pt);
- double paramat;
- pCurve1->getParamAtPoint(pt,paramat);
- intersectpt[j].IntersectParamat.append(paramat);
- }
- }
- //判断pCurve1的端点是否在pCurve容差范围之内,添加到交点表第i条曲线上
- pCurve->getClosestPointTo(pstart1,pt);
- if (pstart1.isEqualTo(pt,tol) && !(pstart0.isEqualTo(pt,tol) || pend0.isEqualTo(pt,tol)))
- {
- double paramat;
- pCurve->getParamAtPoint(pt,paramat);
- intersectpt.IntersectParamat.append(paramat);
- }
- pCurve->getClosestPointTo(pend1,pt);
- if (pend1.isEqualTo(pt,tol) && !(pstart0.isEqualTo(pt,tol) || pend0.isEqualTo(pt,tol)))
- {
- double paramat;
- pCurve->getParamAtPoint(pt,paramat);
- intersectpt.IntersectParamat.append(paramat);
- }
- //判断pCurve的端点是否在pCurve1容差范围之内,添加到交点表第j条曲线上
- pCurve1->getClosestPointTo(pstart0,pt);
- if (pstart0.isEqualTo(pt,tol) && !(pstart1.isEqualTo(pt,tol) || pend1.isEqualTo(pt,tol)))
- {
- double paramat;
- pCurve1->getParamAtPoint(pt,paramat);
- intersectpt[j].IntersectParamat.append(paramat);
- }
- pCurve1->getClosestPointTo(pend0,pt);
- if (pend0.isEqualTo(pt,tol) && !(pstart1.isEqualTo(pt,tol) || pend1.isEqualTo(pt,tol)))
- {
- double paramat;
- pCurve1->getParamAtPoint(pt,paramat);
- intersectpt[j].IntersectParamat.append(paramat);
- }
- pEnt1->close();
- }
- pEnt->close();
- }
- for (long i = 0;i < len;i++)
- {
- //取出第i条曲线pCurve
- Id = IdArray.at(i);
- acdbOpenObject(pEnt,Id,AcDb::kForRead);
- pCurve = AcDbCurve::cast(pEnt);
- //根据点intersectpt打断第i条曲线
- if (!(intersectpt.IntersectParamat.isEmpty()))
- {
- AcGeDoubleArray nPts;
- nPts.setPhysicalLength(0);
- nPts.setLogicalLength(0);
- long inptlen=intersectpt.IntersectParamat.length();
- double *intdouble=new double[inptlen];
- for (long j = 0;j < inptlen;j++)
- {
- intdouble[j]=intersectpt.IntersectParamat.at(j);
- }
- qsort(intdouble,inptlen,sizeof(intdouble[0]),doublecmp);
- for (long i = 0;i < inptlen;i++)
- {
- nPts.append(intdouble);
- }
- delete []intdouble;
- //len1打断曲线前curveSegments的长度
- long len1 = curveSegments.length();
- pCurve->upgradeOpen();
- //按参数表params打断曲线pCurve
- es = pCurve->getSplitCurves(nPts,curveSegments);
- //len2打断曲线后curveSegments的长度
- long len2 = curveSegments.length();
- if ((len2 - len1) > 1)/*生成了新的曲线*/
- {
- //acutPrintf(_T("\n共生成直线 %d 条!"),(len2 - len1));
- pCurve->erase();
- pEnt->close();
- for (int ii = len1; ii <len2; ii++)
- {
- AcDbEntity *pEntity = NULL;
- pEntity = (AcDbEntity *)curveSegments[ii];
- //将生成的曲线添加到数据库
- WTUcreateEnt::PostToModelSpace(pEntity);
- }
- }
- else /*没有生成新曲线*/
- {
- pEnt->close();
- AcDbEntity *pEnt1;
- pEnt1 = (AcDbEntity *)curveSegments[(len2 - 1)];
- delete(pEnt1);
- curveSegments.setAt(len2 - 1,pCurve);
- }
- }
- else /*曲线没有交点,无需打断*/
- {
- pEnt->close();
- curveSegments.append(pCurve);
- }
- }
- delete []intersectpt;
- }
|
|