YSRESULT YsShellExt_RoundUtil3d::CalculateRoundingAll(const YsShell &shl,const double radius) { YsArray <unsigned int> vtKeyArray; YsArray <HalfRoundCorner *> cornerPtrArray; for(auto &corner : cornerArray) { vtKeyArray.Append(shl.GetSearchKey(corner.fromVtHd)); cornerPtrArray.Append(&corner); } YsQuickSort <unsigned int,HalfRoundCorner *> (vtKeyArray.GetN(),vtKeyArray,cornerPtrArray); YsArray <HalfRoundCorner *> cornerPerVertex; for(YSSIZE_T idx=0; idx<cornerPtrArray.GetN(); ++idx) { cornerPerVertex.Append(cornerPtrArray[idx]); if(cornerPtrArray.GetN()-1==idx || vtKeyArray[idx]!=vtKeyArray[idx+1]) { if(YSOK!=CalculateRoundingPerVertex(shl,cornerPerVertex,radius)) { return YSERR; } cornerPerVertex.CleanUp(); } } return YSOK; }
YsArray <const YsShellExt_RoundUtil3d::HalfRoundCorner *> YsShellExt_RoundUtil3d::MakeSortedHalfRoundCorner(const YsShell &shl) const { YsArray <unsigned int> vtKeyArray; YsArray <const HalfRoundCorner *> cornerPtrArray; for(auto &corner : cornerArray) { vtKeyArray.Append(shl.GetSearchKey(corner.fromVtHd)); cornerPtrArray.Append(&corner); } YsQuickSort <unsigned int,const HalfRoundCorner *> (vtKeyArray.GetN(),vtKeyArray,cornerPtrArray); return cornerPtrArray; }
YSRESULT YsShellExt_RoundUtil3d::CalculateRoundingDirectionAll(const YsShell &shl) { YsArray <HalfRoundCorner *> cornerPtrArray=MakeSortedHalfRoundCorner(shl); YsArray <HalfRoundCorner *> cornerPerVertex; for(YSSIZE_T idx=0; idx<cornerPtrArray.GetN(); ++idx) { cornerPerVertex.Append(cornerPtrArray[idx]); if(cornerPtrArray.GetN()-1==idx || cornerPtrArray[idx]->fromVtHd!=cornerPtrArray[idx+1]->fromVtHd) { const YsVec3 roundDir=CalculateRoundingDirction(shl,cornerPerVertex); if(YsOrigin()==roundDir) { return YSERR; } for(auto ptr : cornerPerVertex) { ptr->roundDir=roundDir; } cornerPerVertex.CleanUp(); } } return YSOK; }
YSRESULT YsShellExt_RoundUtil::SetUpRoundConstEdge(const YsShellExt &shl,YsShellExt::ConstEdgeHandle ceHd,const YsShellVertexStore *roundVtx) { YsArray <YsShellVertexHandle> ceVtHd; YSBOOL isLoop; shl.GetConstEdge(ceVtHd,isLoop,ceHd); if(YSTRUE==isLoop && 3>ceVtHd.GetN()) { return YSERR; } else if(YSTRUE!=isLoop && 2>ceVtHd.GetN()) { return YSERR; } if(YSTRUE==isLoop) { ceVtHd.Append(ceVtHd[0]); ceVtHd.Append(ceVtHd[1]); } for(YSSIZE_T idx=1; idx<ceVtHd.GetN()-1; ++idx) { if(NULL==roundVtx || YSTRUE==roundVtx->IsIncluded(ceVtHd[idx])) { const YsShellVertexHandle toVtHd[2]={ceVtHd[idx-1],ceVtHd[idx+1]}; AddRoundCorner((const YsShell &)shl,ceVtHd[idx],toVtHd); } } targetCeKeyArray.Append(shl.GetSearchKey(ceHd)); return YSOK; }
/* static */ void PolyCreFileName::MakeDirectoryForFile(const wchar_t wfn[]) { YsWString ful(wfn),pth,fil; ful.SeparatePathFile(pth,fil); ful=pth; YsArray <YsWString> backTrack; for(;;) { if(ful.LastChar()=='\\' || ful.LastChar()=='/') { ful.BackSpace(); } printf("%ls\n",ful.Txt()); backTrack.Append(ful); YsWString pth,fil; ful.SeparatePathFile(pth,fil); if(0<pth.Strlen() && 0<fil.Strlen()) { ful=pth; } else { break; } } for(YSSIZE_T idx=backTrack.GetN()-1; 0<=idx; --idx) { printf("MkDir %ls\n",backTrack[idx].Txt()); YsFileIO::MkDir(backTrack[idx]); } }
YsArray <YsShellVertexHandle> YsShellExt_SweepInfo::GetVertexAll(void) const { YsArray <YsShellVertexHandle> vtHdArray; for(auto vtHd : allSrcVtHd) { vtHdArray.Append(vtHd); } return vtHdArray; }
void YsShellExt_SweepInfo::MakeInfo( const YsShellExt &shl, YSSIZE_T nPl,const YsShellPolygonHandle plHdArray[], YSSIZE_T nCe,const YsShellExt::ConstEdgeHandle ceHdArray[]) { CleanUp(); YsShellExt_BoundaryInfo::MakeInfo(*(const YsShell *)&shl,nPl,plHdArray); allSrcVtHd.SetShell((const YsShell &)shl); for(YSSIZE_T idx=0; idx<nPl; ++idx) { YsArray <YsShellVertexHandle,4> plVtHd; shl.GetPolygon(plVtHd,plHdArray[idx]); for(auto vtHd : plVtHd) { allSrcVtHd.AddVertex(vtHd); } } for(YSSIZE_T idx=0; idx<nCe; ++idx) { YsArray <YsShellVertexHandle,4> ceVtHd; YSBOOL isLoop; shl.GetConstEdge(ceVtHd,isLoop,ceHdArray[idx]); for(auto vtHd : ceVtHd) { allSrcVtHd.AddVertex(vtHd); } } for(YSSIZE_T ceIdx=0; ceIdx<nCe; ++ceIdx) { YSBOOL isLoop; YsArray <YsShellVertexHandle,16> ceVtHd; shl.GetConstEdge(ceVtHd,isLoop,ceHdArray[ceIdx]); if(2<=ceVtHd.GetN()) { if(YSTRUE==isLoop) { YsShellVertexHandle first=ceVtHd[0]; ceVtHd.Append(first); } for(int edIdx=0; edIdx<ceVtHd.GetN()-1; ++edIdx) { if(YSTRUE!=visited.IsIncluded(ceVtHd[edIdx],ceVtHd[edIdx+1])) { visited.AddEdge(ceVtHd[edIdx],ceVtHd[edIdx+1]); srcEdVtHd.Append(ceVtHd[edIdx]); srcEdVtHd.Append(ceVtHd[edIdx+1]); } } } } }
YsArray <YsShellExt::VolumeHandle> YsShellExt_DuplicateUtil::GetNonDerivedNewVolume(void) const { YsArray <YsShellExt::VolumeHandle> ary; for(auto elem : volumeArray) { if(YSTRUE!=elem.derived) { ary.Append(elem.newVlHd); } } return ary; }
YsArray <YsShellExt::FaceGroupHandle> YsShellExt_DuplicateUtil::GetNonDerivedNewFaceGroup(void) const { YsArray <YsShellExt::FaceGroupHandle> ary; for(auto elem : faceGroupArray) { if(YSTRUE!=elem.derived) { ary.Append(elem.newFgHd); } } return ary; }
YsArray <YsShellPolygonHandle> YsShellExt_DuplicateUtil::GetNonDerivedNewPolygon(void) const { YsArray <YsShellPolygonHandle> ary; for(auto elem : polygonArray) { if(YSTRUE!=elem.derived) { ary.Append(elem.newPlHd); } } return ary; }
YsArray <YsShellVertexHandle> YsShellExt_DuplicateUtil::GetNonDerivedNewVertex(void) const { YsArray <YsShellVertexHandle> ary; for(auto elem : vertexArray) { if(YSTRUE!=elem.derived) { ary.Append(elem.newVtHd); } } return ary; }
YsArray <YSSIZE_T> YsShellExt_RoundUtil3d::FindHalfRoundCornerFromPolygon(const YsShell &shl,YsShellPolygonHandle plHd) const { YsArray <YsShellVertexHandle,4> plVtHd; shl.GetPolygon(plVtHd,plHd); YsArray <YSSIZE_T> idxArray; for(YSSIZE_T i=0; i<plVtHd.GetN(); ++i) { for(YSSIZE_T j=0; j<cornerArray.GetN(); ++j) { if(plVtHd[i]==cornerArray[j].fromVtHd && YSTRUE==plVtHd.IsIncluded(cornerArray[j].toVtHd)) { idxArray.Append(j); } } } return idxArray; }
YSRESULT YsShellExt_SweepInfoMultiStep::SetUpNonParallelSweepWithPath(const YsShellExt &shl,YSSIZE_T nPathVt,const YsShellVertexHandle pathVtHdArrayIn[],YSBOOL isLoop,const double scaling[],ORIENTATION_CONTROL_TYPE oriconTypeMid,ORIENTATION_CONTROL_TYPE oriconTypeLast) { YsArray <YsShellVertexHandle> pathVtHd(nPathVt,pathVtHdArrayIn); for(auto idx=pathVtHd.GetN()-1; 0<idx; --idx) { if(pathVtHd[idx]==pathVtHd[idx-1]) { pathVtHd.Delete(idx); } } if(0<pathVtHd.GetN() && pathVtHd.Last()==pathVtHd[0]) { pathVtHd.DeleteLast(); isLoop=YSTRUE; } if(2>pathVtHd.GetN() || (YSTRUE==isLoop && 3>pathVtHd.GetN())) { return YSERR; } const auto &allVtHd=GetVertexAll(); YsArray <YsVec3> iniPos; for(auto vtHd : allVtHd) { iniPos.Append(shl.GetVertexPosition(vtHd)); } YsVec3 lfpNom; if(YSOK!=YsFindLeastSquareFittingPlaneNormal(lfpNom,iniPos)) { return YSERR; } if(0.0>lfpNom*(shl.GetVertexPosition(pathVtHd[1])-shl.GetVertexPosition(pathVtHd[0]))) { lfpNom=-lfpNom; } YsArray <YsVec3> nomArray(nPathVt,NULL); nomArray[0]=lfpNom; for(YSSIZE_T idx=1; idx<nPathVt-1; ++idx) { switch(oriconTypeMid) { case ORICON_PREVIOUS_SEGMENT: nomArray[idx]=YsUnitVector(shl.GetVertexPosition(pathVtHd[idx])-shl.GetVertexPosition(pathVtHd[idx-1])); break; case ORICON_NEXT_SEGMENT: nomArray[idx]=YsUnitVector(shl.GetVertexPosition(pathVtHd[idx+1])-shl.GetVertexPosition(pathVtHd[idx])); break; case ORICON_AVERAGE_ANGLE: { auto v1=YsUnitVector(shl.GetVertexPosition(pathVtHd[idx])-shl.GetVertexPosition(pathVtHd[idx-1])); auto v2=YsUnitVector(shl.GetVertexPosition(pathVtHd[idx+1])-shl.GetVertexPosition(pathVtHd[idx])); nomArray[idx]=YsUnitVector(v1+v2); } break; case ORICON_FROMPREVPOINT_TO_NEXTPOINT: nomArray[idx]=YsUnitVector(shl.GetVertexPosition(pathVtHd[idx+1])-shl.GetVertexPosition(pathVtHd[idx-1])); break; } } switch(oriconTypeLast) { case ORICON_PREVIOUS_SEGMENT: case ORICON_NEXT_SEGMENT: nomArray.Last()=YsUnitVector(shl.GetVertexPosition(pathVtHd[nPathVt-1])-shl.GetVertexPosition(pathVtHd[nPathVt-2])); break; case ORICON_AVERAGE_ANGLE: // There's no next point case ORICON_FROMPREVPOINT_TO_NEXTPOINT: // There's no next point if(YSTRUE==isLoop) { YsVec3 v1=YsUnitVector(shl.GetVertexPosition(pathVtHd[0])-shl.GetVertexPosition(pathVtHd[nPathVt-1])); YsVec3 v2=YsUnitVector(shl.GetVertexPosition(pathVtHd[nPathVt-1])-shl.GetVertexPosition(pathVtHd[nPathVt-2])); v1.Normalize(); v2.Normalize(); nomArray.Last()=YsUnitVector(v1+v2); } else { nomArray.Last()=YsUnitVector(shl.GetVertexPosition(pathVtHd[nPathVt-1])-shl.GetVertexPosition(pathVtHd[nPathVt-2])); } break; } return SetUpNonParallelSweepWithPath(shl,nPathVt,pathVtHd,isLoop,nomArray,scaling); }
YSRESULT YsShell::MergeMs3(const char fn[]) { FILE *fp; YsArray <YsShellVertexHandle> vtHdList; fp=fopen(fn,"r"); if(fp!=NULL) { char buf[256]; YsShellVertexHandle plVtHd[4]; while(fgets(buf,255,fp)!=NULL) { if('#'==buf[0]) { continue; } int ac; char *av[16]; if(YsArguments(&ac,av,16,buf)==YSOK && ac>0) { if(av[0][0]=='v' || av[0][0]=='V') { if(ac>=4) { YsShellVertexHandle vtHd; YsVec3 pos; double x,y,z; x=atof(av[1]); y=atof(av[2]); z=atof(av[3]); pos.Set(x,y,z); vtHd=AddVertexH(pos); vtHdList.Append(vtHd); } else { goto ERREND; } } else if(av[0][0]=='D' || av[0][0]=='d') // D:Delta=Triangle { if(ac>=4) { plVtHd[0]=vtHdList[atoi(av[1])]; plVtHd[1]=vtHdList[atoi(av[2])]; plVtHd[2]=vtHdList[atoi(av[3])]; SetColorOfPolygon(AddPolygonH(3,plVtHd),YsBlue()); } else { goto ERREND; } } else if(av[0][0]=='Q' || av[0][0]=='q') { if(ac>=5) { plVtHd[0]=vtHdList[atoi(av[1])]; plVtHd[1]=vtHdList[atoi(av[2])]; plVtHd[2]=vtHdList[atoi(av[3])]; plVtHd[3]=vtHdList[atoi(av[4])]; SetColorOfPolygon(AddPolygonH(4,plVtHd),YsBlue()); } else { goto ERREND; } } } } fclose(fp); return YSOK; } ERREND: if(fp!=NULL) { fclose(fp); } return YSERR; }
void YsArguments2(YsArray <YsString,16> &args,const char vv[],YSSIZE_T l,const char *blank,const char *comma) { YsString empty; args.Set(0,NULL); YSSIZE_T i=0; while(YSTRUE==CharIsOneOf(vv[i],blank)) { i++; } YSSIZE_T head=i; while(i<l) { if(vv[head]=='\"') { head++; i++; while(i<l && vv[i]!='\"') { if(vv[i]&0x80) // 1st letter of Kanji character? { i++; } else if(isprint(vv[i])==0) { break; } i++; } args.Append(empty); args[args.GetN()-1].Set(i-head,vv+head); if(vv[i]=='\"') { i++; } } else { while(i<l && (CharIsOneOf(vv[i],blank)!=YSTRUE && CharIsOneOf(vv[i],comma)!=YSTRUE)) { if(vv[i]&0x80) // 1st letter of Kanji character? { i++; } else if(isprint(vv[i])==0) { break; } i++; } if(head<i) // <- This condition is added on 2005/03/03 { args.Append(empty); args[args.GetN()-1].Set(i-head,vv+head); } else if(head==i && YSTRUE==CharIsOneOf(vv[i],comma)) // < This condition is added (I thought there was, did I accidentally delet?) on 2012/01/26 { args.Increment(); args.GetEnd().Set(""); } } while(i<l && isprint(vv[i])==0) { i++; } while(i<l && CharIsOneOf(vv[i],blank)==YSTRUE) // Skip blank separator { i++; } if(CharIsOneOf(vv[i],comma)==YSTRUE) // Skip one comma separator { i++; while(i<l && CharIsOneOf(vv[i],blank)==YSTRUE) // Skip blank separator after a comma separator { i++; } if(i==l) { args.Append(empty); } } head=i; } }
void YsShellExt_SewingInfo::MakePolygonSplitInfo(const YsShellExt &shl) { // A concave polygon may be cut twice by one crawling. YsShellPolygonAttribTable <YsArray <YsArray <YsShellVertexHandle,2> > > plHdToDivider(shl.Conv()); for(auto &v : vtxSequence) { if(NULL==v.vtHd) { if(0<=v.vtxOnEdgeIdx) { v.vtHd=vtxOnEdge[v.vtxOnEdgeIdx].createdVtHd; } else if(0<=v.vtxOnPlgIdx) { v.vtHd=vtxOnPlg[v.vtxOnPlgIdx].vtHd; } } } { YsShellPolygonHandle currentPlHd=NULL; YsArray <YsShellVertexHandle,2> currentDivider; for(YSSIZE_T idx=0; idx<vtxSequence.GetN(); ++idx) { if(0==currentDivider.GetN()) { currentPlHd=vtxSequence[idx].plHd; currentDivider.Append(vtxSequence[idx].vtHd); } else { currentDivider.Append(vtxSequence[idx].vtHd); if(idx==vtxSequence.GetN()-1 || vtxSequence[idx].plHd!=currentPlHd) { if(2<=currentDivider.GetN()) { YsArray <YsArray <YsShellVertexHandle,2> > *pldv=plHdToDivider[currentPlHd]; if(NULL==pldv) { YsArray <YsArray <YsShellVertexHandle,2> > newDividerArray(1,NULL); newDividerArray[0].MoveFrom(currentDivider); plHdToDivider.SetAttrib(currentPlHd,newDividerArray); } else { pldv->Append(currentDivider); } } currentDivider.CleanUp(); currentDivider.Append(vtxSequence[idx].vtHd); } currentPlHd=vtxSequence[idx].plHd; } } } for(auto hashHd : plHdToDivider.AllHandle()) { auto plKey=plHdToDivider.GetKey(hashHd); auto plHd=shl.FindPolygon(plKey); auto ÷r=*plHdToDivider[plHd]; YsSegmentedArray <YsArray <YsShellVertexHandle,4>,4> plVtHd(1,NULL); plVtHd[0]=shl.GetPolygonVertex(plHd); for(auto d : divider) { YsArray <YsShellVertexHandle,4> fragment; for(auto &pl : plVtHd) { if(YSOK==YsShellExt_SplitLoopByHandleAndMidNode(pl,fragment,d)) { plVtHd.Append(fragment); break; } } } plgSplit.Increment(); plgSplit.Last().plHd=plHd; plgSplit.Last().plVtHdArray=plVtHd; } }
YSRESULT YsShell::MergeDat(const char fn[]) { FILE *fp; YsArray <YsShellVertexHandle> vtHdList; fp=fopen(fn,"r"); if(fp!=NULL) { char buf[4096]; YsArray <YsShellVertexHandle,64> plVtHd; while(fgets(buf,4095,fp)!=NULL) { int ac; char *av[1024]; if(YsArguments(&ac,av,1024,buf)==YSOK && ac>0) { if(av[0][0]=='v' || av[0][0]=='V') { if(ac>=4) { YsShellVertexHandle vtHd; YsVec3 pos; double x,y,z; x=atof(av[1]); y=atof(av[2]); z=atof(av[3]); pos.Set(x,y,z); vtHd=AddVertexH(pos); vtHdList.Append(vtHd); } else { goto ERREND; } } else if(av[0][0]=='f' || av[0][0]=='F') // D:Delta=Triangle { if(ac>=4) { int i; YsShellPolygonHandle plHd; plVtHd.Set(ac-1,NULL); for(i=0; i<ac-1; i++) { plVtHd[i]=vtHdList[atoi(av[i+1])]; } plHd=AddPolygonH(ac-1,vtHdList); SetColorOfPolygon(plHd,YsBlue()); } else { goto ERREND; } } } } fclose(fp); return YSOK; } ERREND: if(fp!=NULL) { fclose(fp); } return YSERR; }
YSRESULT YsShellExt_RoundUtil3d::SetUpForAroundPolygonGroup( const YsShellExt &shl, YSSIZE_T nPl,const YsShellPolygonHandle plHdArray[]) { CleanUp(); if(YSTRUE!=shl.IsSearchEnabled()) { YsPrintf("%s\n",__FUNCTION__); YsPrintf(" This function requires a search table.\n"); return YSERR; } YsShellExt_BoundaryInfo boundary; boundary.MakeInfo((const YsShell &)shl,nPl,plHdArray); if(YSOK!=boundary.CacheContour((const YsShell &)shl)) { return YSERR; } YsShellPolygonStore sideAPolygon((const YsShell &)shl),sideBPolygon((const YsShell &)shl); sideAPolygon.AddPolygon(nPl,plHdArray); YsArray <YsShellPolygonHandle> sideAPolygonArray(nPl,plHdArray),sideBPolygonArray; YsShellEdgeStore boundaryEdge((const YsShell &)shl); for(YSSIZE_T contourIdx=0; contourIdx<boundary.GetNumContour(); ++contourIdx) { YsArray <YsShellVertexHandle> contourVtHd; boundary.GetContour(contourVtHd,contourIdx); if(3<=contourVtHd.GetN()) { if(contourVtHd[0]!=contourVtHd.Last()) { const YsShellVertexHandle vtHd0=contourVtHd[0]; contourVtHd.Append(vtHd0); } for(YSSIZE_T vtIdx=0; vtIdx<contourVtHd.GetN()-1; ++vtIdx) { boundaryEdge.AddEdge(contourVtHd[vtIdx],contourVtHd[vtIdx+1]); YSSIZE_T nVtPl; const YsShellPolygonHandle *vtPlHd; shl.FindPolygonFromVertex(nVtPl,vtPlHd,contourVtHd[vtIdx]); for(YSSIZE_T plIdx=0; plIdx<nVtPl; ++plIdx) { if(YSTRUE!=sideAPolygon.IsIncluded(vtPlHd[plIdx]) && YSTRUE!=sideBPolygon.IsIncluded(vtPlHd[plIdx])) { sideBPolygon.AddPolygon(vtPlHd[plIdx]); sideBPolygonArray.Append(vtPlHd[plIdx]); } } } } } return SetUpForVertexSequenceAndPolygonArray( shl, boundary.GetContourAll(), sideAPolygonArray, sideBPolygonArray); }
YsArray <YsShellExt_RoundUtil::VertexPositionPair> YsShellExt_RoundUtil::MakeRoundedVertexSequence(const YsShell &shl,YSSIZE_T nVt,const YsShellVertexHandle vtHdArrayIn[],YSBOOL isLoop) const { YsArray <YsShellVertexHandle> orgVtHdArray(nVt,vtHdArrayIn); YsArray <VertexPositionPair> newVtHdArray; for(YSSIZE_T orgVtIdx=0; orgVtIdx<orgVtHdArray.GetN(); ++orgVtIdx) { YSBOOL rounded=YSFALSE; for(const auto &roundCorner : cornerArray) { if(roundCorner.fromVtHd==orgVtHdArray[orgVtIdx]) { int forward=0,backward=1; if(roundCorner.toVtHd[0]==orgVtHdArray.GetCyclic(orgVtIdx-1)) { forward=1; backward=0; } else if(roundCorner.toVtHd[1]==orgVtHdArray.GetCyclic(orgVtIdx-1)) { forward=0; backward=1; } else { continue; } YSBOOL skipFirst=YSFALSE; if(0<newVtHdArray.GetN() && newVtHdArray.Last().pos==roundCorner.subDiv[backward].Last().pos) { skipFirst=YSTRUE; } newVtHdArray.Append(roundCorner.subDiv[backward]); newVtHdArray.Increment(); newVtHdArray.Last().vtHd=orgVtHdArray[orgVtIdx]; newVtHdArray.Last().pos=roundCorner.roundedCornerPos; for(YSSIZE_T i=roundCorner.subDiv[forward].GetN()-1; 0<=i; --i) { if(YSTRUE==skipFirst) { skipFirst=YSFALSE; continue; } newVtHdArray.Append(roundCorner.subDiv[forward][i]); } rounded=YSTRUE; } } if(YSTRUE!=rounded) { newVtHdArray.Increment(); newVtHdArray.Last().vtHd=orgVtHdArray[orgVtIdx]; newVtHdArray.Last().pos=shl.GetVertexPosition(newVtHdArray.Last().vtHd); } } if(2<=newVtHdArray.GetN() && YSTRUE==isLoop && newVtHdArray[0].pos==newVtHdArray.Last().pos) { newVtHdArray.DeleteLast(); } return newVtHdArray; }