2005年01月26日

PointMoveOnEdge2

途中経過

ポイント移動に使うデータベースの構築とワイヤフレーム表示まで出来た
Build関数部分ではポイントの移動だけなので、pntMoveで新しい座標入れればいいやなんて思っていたら、 pntMoveでエラーが返ってくる
返り値は2なので不正なレイヤーに対する操作をしたというエラー
addPointとか追加するのはエラーが起きない

 

構造体とか

typedef LWError (*BuildFunc)(LWInstance inst, MeshEditOp *mesh);

typedef struct {
 LWPntID     pnt[2];
 LWFVector    pos[2];
}EdgeData;

typedef struct {
 LWPntID  id;
 LWDVector vec;
}PDVector;

typedef struct {
 LWPntID     id;
 LWDVector    newPos;
 LWDVector    orgPos;
 std::vector<PDVector> edges;
}PointData;

typedef struct {
 GlobalFunc    *global;
 MeshEditOp    *edit;
 BuildFunc    func;
 std::vector<PointData> points;
 int      numPoints;
 int      curIndex;
 std::vector<EdgeData> lines;
 int      update;
 int      dirty;
}MyData;

データベース構築部分

MyData->funcをBuild関数で実行する、データの初期化時にinitDataを代入してる
MyData->linesはワイヤーフレーム表示用のデータ、両端の座標を持ってる
PointData->edgesは移動用のデータ、隣接する点の相対座標のリスト

EDError getSelPoints(void *scanData, const EDPointInfo *info)
{
 MyData  *data = (MyData*)scanData;
 PointData pnt;

 if( info->flags & EDDF_SELECT ){
  pnt.id = info->pnt;
  memcpy(pnt.orgPos, info->position, sizeof(LWDVector));
  memcpy(pnt.newPos, info->position, sizeof(LWDVector));
  data->points.push_back(pnt);
 }
 return EDERR_NONE;
}

EDError getEdge(void *scanData, const EDPolygonInfo *info)
{
 MyData        *data = (MyData*)scanData;
 std::vector<PointData>::iterator pnt = data->points.begin() + data->curIndex;
 EdgeData       edge[2];
 EDPointInfo       *pntInfo;
 PDVector       pvec[2];

 if( 2 > info->numPnts ) return EDERR_NONE;

 for(int i=0; i<info->numPnts; i++){
  //この頂点(pnt->id)がポリゴンに含まれているかチェック
  if( info->points[i] == pnt->id ){
   //含まれていたらこの頂点が始点になるように線データを格納
   edge[0].pnt[0] = pnt->id;
   edge[1].pnt[0] = pnt->id;
   if( (i+1) >= info->numPnts ){
    edge[0].pnt[1] = pvec[0].id = info->points[0];
    edge[1].pnt[1] = pvec[1].id = info->points[i-1];
   }else if( 0 == i){
    edge[0].pnt[1] = pvec[0].id = info->points[1];
    edge[1].pnt[1] = pvec[1].id = info->points[info->numPnts-1];
   }else{
    edge[0].pnt[1] = pvec[0].id = info->points[i+1];
    edge[1].pnt[1] = pvec[1].id = info->points[i-1];
   }
   //この線データがデータベースに含まれていなければデータベースに追加
   for(int j=0; j<2; j++){
    //描画用線データ
    for(int k=0; k<data->lines.size(); k++){
     if( edge[j].pnt[1] == data->lines[k].pnt[1] && edge[j].pnt[0] == data->lines[k].pnt[0] ) break;
    }
    if( data->lines.size() == k ){
     for(k=0; k<3; k++) edge[j].pos[0][k] = (float)pnt->orgPos[k];
     pntInfo = data->edit->pointInfo(data->edit->state, edge[j].pnt[1]);
     for(k=0; k<3; k++) edge[j].pos[1][k] = (float)pntInfo->position[k];
     data->lines.push_back(edge[j]);
    }
    //ポイント移動用線データ
    for(k=0; k<pnt->edges.size(); k++){
     if( pvec[j].id == pnt->edges[k].id ) break;
    }
    if( pnt->edges.size() == k ){
     pntInfo = data->edit->pointInfo(data->edit->state, pvec[j].id);
     pvec[j].vec[0] = pntInfo->position[0] - pnt->orgPos[0];
     pvec[j].vec[1] = pntInfo->position[1] - pnt->orgPos[1];
     pvec[j].vec[2] = pntInfo->position[2] - pnt->orgPos[2];
     pnt->edges.push_back(pvec[j]);
    }
   }//---ここまで (この線データがデータベースに含まれていなければデータベースに追加
   break;
  }//---ここまで (この頂点(pnt->id)がポリゴンに含まれているかチェック
 }

 return EDERR_NONE;
}

LWError initData(LWInstance inst, MeshEditOp *edit)
{
 MyData *data = (MyData*)inst;

 data->numPoints = edit->pointCount(edit->state, OPLYR_PRIMARY, EDCOUNT_SELECT);
 if( 0 == data->numPoints ) return "選択されたポイントが無い";

 edit->pointScan(edit->state, getSelPoints, data, OPLYR_PRIMARY);

 data->edit = edit;
 for(int i=0; i<data->numPoints; i++){
  data->curIndex = i;
  edit->polyScan(edit->state, getEdge, data, OPLYR_PRIMARY);
 }

 data->func = buildFunc;

 return NULL;
}

ワイヤーフレーム表示部分

XCALL_(void)
Draw(LWInstance inst, LWWireDrawAccess *access)
{
 MyData  *data = (MyData*)inst;
 LWFVector fvec;
 
 int numEdge = data->lines.size();
 for(int i=0; i<numEdge; i++){
  access->moveTo(access->data, data->lines[i].pos[0], LWWIRE_SOLID);
  access->lineTo(access->data, data->lines[i].pos[1], LWWIRE_ABSOLUTE);
 }
 for(i=0; i<data->numPoints; i++){
  fvec[0] = (float)data->points[i].newPos[0];
  fvec[1] = (float)data->points[i].newPos[1];
  fvec[2] = (float)data->points[i].newPos[2];
  access->moveTo(access->data, fvec, LWWIRE_SOLID);
  access->circle(access->data, 0.5, LWWIRE_SCREEN);
 }
}

 

posted by toka at 14:53| Comment(0) | TrackBack(0) | LWプラグイン開発 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:


この記事へのトラックバック