#include "..//Core//sg.h" #include /************************************************************************/ /* Boundary representation piece */ /************************************************************************/ sgCBRepPiece::sgCBRepPiece(): m_vertexes(NULL) ,m_vertexes_count(0) ,m_edges(NULL) ,m_edges_count(0) { m_brep_piece_handle = creat_np_mem(TNPW,MAXNOV,MAXNOE,MAXNOC,MAXNOF,MAXNOE); assert(m_brep_piece_handle!=NULL); memset(&m_min,0,sizeof(SG_POINT)); memset(&m_max,0,sizeof(SG_POINT)); m_min_triangle_number = 0; m_max_triangle_number = 0; } sgCBRepPiece::~sgCBRepPiece() { if (m_brep_piece_handle) { free_np_mem((lpNPW*)(&m_brep_piece_handle)); m_brep_piece_handle = NULL; } if (m_vertexes) { SGFree(m_vertexes); m_vertexes = NULL; } m_vertexes_count = 0; if (m_edges) { SGFree(m_edges); m_edges = NULL; } m_edges_count = 0; } void sgCBRepPiece::GetLocalGabarits(SG_POINT& p_min, SG_POINT& p_max) const { memcpy(&p_min,&m_min,sizeof(SG_POINT)); memcpy(&p_max,&m_max,sizeof(SG_POINT)); } void sgCBRepPiece::GetTrianglesRange(int& min_numb, int& max_numb) const { min_numb = m_min_triangle_number; max_numb = m_max_triangle_number; } const SG_POINT* sgCBRepPiece::GetVertexes() const {return m_vertexes;} unsigned int sgCBRepPiece::GetVertexesCount() const {return m_vertexes_count;} const SG_EDGE* sgCBRepPiece::GetEdges() const {return m_edges;} unsigned int sgCBRepPiece::GetEdgesCount() const {return m_edges_count;} /************************************************************************/ /* Boundary representation */ /************************************************************************/ sgCBRep::sgCBRep(): m_pieces(NULL) ,m_pieces_count(0) { } sgCBRep::~sgCBRep() { if (m_pieces) { for (unsigned int i=0;i=m_pieces_count) return NULL; return m_pieces[nmbr]; } unsigned int sgCBRep::GetPiecesCount() const {return m_pieces_count;} /************************************************************************/ /* 3D Object */ /************************************************************************/ static bool auto_triangulation = false; static SG_TRIANGULATION_TYPE auto_triangulation_type = SG_DELAUNAY_TRIANGULATION; SG_TRIANGULATION_TYPE triangulation_temp_flag = auto_triangulation_type; void sgC3DObject::AutoTriangulate(bool aTr, SG_TRIANGULATION_TYPE trType) { auto_triangulation = aTr; auto_triangulation_type = trType; } sgC3DObject::sgC3DObject():sgCObject() { m_objectType = SG_UNKNOWN_3D; m_brep = NULL; m_triangles = NULL; m_world_matrix = NULL; m_material = NULL; } sgC3DObject::~sgC3DObject() { if (m_brep) { delete m_brep; m_brep = NULL; } if (m_triangles!=NULL) { if (m_triangles->allUV!=NULL) free(m_triangles->allUV); if (m_triangles->allNormals!=NULL) free(m_triangles->allNormals); if (m_triangles->allVertex!=NULL) free(m_triangles->allVertex); free(m_triangles); } if (m_world_matrix!=NULL) delete m_world_matrix; if (m_material) delete m_material; } sgC3DObject::sgC3DObject(SG_OBJ_HANDLE objH):sgCObject(objH) { m_objectType = SG_UNKNOWN_3D; m_brep = NULL; m_triangles = NULL; m_material = NULL; //DECLARE_PERFORMANCE_FILE_STREAM(LAST_TR.log, perfFile); //DECLARE_PERFORMANCE_CHECKER(1, perfFile); //START_PERFORMANCE_CHECK(1); if (auto_triangulation) Triangulate(auto_triangulation_type); //FINISH_PERFORMANCE_CHECK(1); MATR mtrx; place_ucs_to_lcs_common(GetObjectHandle(this), mtrx, FALSE); m_world_matrix = new sgCMatrix(mtrx); m_world_matrix->Transparent(); GetMaterial(); PostCreate(); } SG_3DOBJECT_TYPE sgC3DObject::Get3DObjectType() const {return m_objectType;} sgCBRep* sgC3DObject::GetBRep() const { return m_brep; } bool sgC3DObject::ApplyTempMatrix() { if (!sgCObject::ApplyTempMatrix()) return false; m_world_matrix->Transparent(); m_world_matrix->Multiply(*m_temp_matrix); m_world_matrix->Transparent(); return true; } const sgFloat* sgC3DObject::GetWorldMatrixData() const { if (!m_world_matrix) { assert(0); return NULL; } return m_world_matrix->GetData(); } static OSCAN_COD edgesBr_pre_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static OSCAN_COD edgesBr_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); static NP_STR_LIST list_str; bool sgC3DObject::CopyBRepStructure() { if (m_brep==NULL) { assert(0); return false; } SCAN_CONTROL sc; OSCAN_COD cod; init_scan(&sc); sc.user_pre_scan = edgesBr_pre_scan; sc.user_geo_scan = edgesBr_geo_scan; sc.data = this; cod = o_scan(GetObjectHandle(this),&sc); return true; } static OSCAN_COD soloBr_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static OSCAN_COD soloBr_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static void FillTriangBrep(); static SG_ALL_TRIANGLES* triangles_of_cur_object = NULL; static hOBJ localObjForMirrorCheck; static BOOL IsMatrixMirror(); #include "..//Core//Aplicat//Delone//BREPTriangulator.h" bool sgC3DObject::Triangulate(SG_TRIANGULATION_TYPE trTp) { if (m_brep) { delete m_brep; m_brep = NULL; } if (m_triangles!=NULL) { if (m_triangles->allUV!=NULL) free(m_triangles->allUV); if (m_triangles->allNormals!=NULL) free(m_triangles->allNormals); if (m_triangles->allVertex!=NULL) free(m_triangles->allVertex); free(m_triangles); } m_brep = new sgCBRep; m_triangles = NULL; CopyBRepStructure(); SCAN_CONTROL sc; OSCAN_COD cod; m_triangles = (SG_ALL_TRIANGLES*)malloc(sizeof(SG_ALL_TRIANGLES)); if (m_triangles==NULL) return false; memset(m_triangles,0,sizeof(SG_ALL_TRIANGLES)); triangles_of_cur_object = m_triangles; triangulation_temp_flag = trTp; CBREPTriangulator* brTr = new CBREPTriangulator(GetObjectHandle(this)); init_scan(&sc); // sc.user_geo_scan = soloBr_geo_scan; sc.user_post_scan = soloBr_post_scan; sc.data = brTr; cod = o_scan(GetObjectHandle(this),&sc); switch ( cod ) { case OSTRUE: break; case OSFALSE: free(m_triangles); return false; } //RA --- fflush(brfl); //RA --- fclose(brfl); localObjForMirrorCheck = GetObjectHandle(this); //FillTriangBrep(); brTr->EndTriangulate(); triangles_of_cur_object->nTr = brTr->GetTrianglesCount(); if(triangles_of_cur_object->nTr) { triangles_of_cur_object->allVertex = brTr->GetTrianglesPoints(); triangles_of_cur_object->allNormals = brTr->GetTrianglesNormals(); triangles_of_cur_object->allColors = brTr->GetTrianglesColors(); } // // - if(IsMatrixMirror()) { for(int m = 0; m < 3*triangles_of_cur_object->nTr; m += 3) { triangles_of_cur_object->allNormals[m].x = -triangles_of_cur_object->allNormals[m].x; triangles_of_cur_object->allNormals[m].y = -triangles_of_cur_object->allNormals[m].y; triangles_of_cur_object->allNormals[m].z = -triangles_of_cur_object->allNormals[m].z; triangles_of_cur_object->allNormals[m+1].x = -triangles_of_cur_object->allNormals[m+1].x; triangles_of_cur_object->allNormals[m+1].y = -triangles_of_cur_object->allNormals[m+1].y; triangles_of_cur_object->allNormals[m+1].z = -triangles_of_cur_object->allNormals[m+1].z; triangles_of_cur_object->allNormals[m+2].x = -triangles_of_cur_object->allNormals[m+2].x; triangles_of_cur_object->allNormals[m+2].y = -triangles_of_cur_object->allNormals[m+2].y; triangles_of_cur_object->allNormals[m+2].z = -triangles_of_cur_object->allNormals[m+2].z; } } delete brTr; return true; } #pragma argsused static OSCAN_COD soloBr_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { return OSTRUE; } #pragma argsused static OSCAN_COD soloBr_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { unsigned int ii/*, ic*/; //short edge; OSCAN_COD cod = OSTRUE; BYTE TypeFace; BYTE bIsUV; #ifndef NEW_TRIANGULATION NP_STR str; #endif if (lpsc->type!=OBREP) return OSTRUE; // BREP, //====================================================== TypeFace = SG_L_NP_SOFT; bIsUV = 0; if ( lpsc->breptype == FRAME ) return OSTRUE; #ifndef NEW_TRIANGULATION if ( scan_flg_np_begin ) if ( !np_init_list(&list_str) ) return OSFALSE; npwg->type = TNPW; if ( !np_cplane(npwg) ) { cod = OSFALSE; goto end; } // - - if ( !(np_put(npwg,&list_str)) ) { cod = OSFALSE; goto end; } #endif if ( !scan_flg_np_end ) return OSTRUE; //------- ----------- { sgC3DObject* obj3D = reinterpret_cast((static_cast(hobj))->extendedClass); sgCBRep* brep = obj3D->GetBRep(); unsigned int pCnt = 0; #ifndef NEW_TRIANGULATION pCnt = list_str.number_all; #else pCnt = brep->GetPiecesCount(); int start_tr_number = 0; int end_tr_number = 0; int tmp_tr_cnt = 0; #endif for (ii = 0; ii < pCnt; ii++) { CBREPTriangulator* brTr = reinterpret_cast(lpsc->data); #ifndef NEW_TRIANGULATION read_elem(&list_str.vdim, ii, &str); if (!(read_np(&list_str.bnp, str.hnp, npwg))) { // FRAME cod=OSFALSE; goto end1; } brTr->TriangulateOneNP(&list_str, npwg); #else brTr->TriangulateOneNP(ii,tmp_tr_cnt); end_tr_number = start_tr_number+tmp_tr_cnt-1; SetBRepPieceMinTriangleNumber(brep->GetPiece(ii),start_tr_number); SetBRepPieceMaxTriangleNumber(brep->GetPiece(ii),end_tr_number); start_tr_number = end_tr_number+1; #endif } #ifndef NEW_TRIANGULATION end1: #endif ; } #ifndef NEW_TRIANGULATION end: np_end_of_put(&list_str,NP_CANCEL,0,NULL); #endif return cod; } static OSCAN_COD setColor_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static OSCAN_COD setColor_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // void sgC3DObject::SetColor(const SG_POINT& colorVal) { SG_POINT color = colorVal; SCAN_CONTROL sc; init_scan(&sc); // sc.user_geo_scan = setColor_geo_scan; sc.user_post_scan = setColor_post_scan; sc.data = &color; o_scan(GetObjectHandle(this),&sc); PostCreate(); } ///////////////////////////////////////////////////////////////////////////////////// // HACK WARNING: The code below is a hack that works around the current architecture // without changing it significantly. #pragma argsused static OSCAN_COD setColor_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { return OSTRUE; } #pragma argsused static OSCAN_COD setColor_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { OSCAN_COD cod = OSTRUE; BYTE TypeFace; BYTE bIsUV; if (lpsc->type!=OBREP) return OSTRUE; // BREP, //====================================================== TypeFace = SG_L_NP_SOFT; bIsUV = 0; if ( lpsc->breptype == FRAME ) return OSTRUE; if ( !scan_flg_np_end ) return OSTRUE; if (!lpsc->data) return OSFALSE; { lpOBJ obj; OSCAN_COD cod = OSTRUE; VI_LOCATION viloc; short i,num_np; lpLNP lnp; int num; obj = (lpOBJ)hobj; num = ((lpGEO_BREP)(obj->geo_data))->num; lnp = (lpLNP)get_elem(&vd_brep, num); get_first_np_loc( &lnp->listh, &lpsc->viloc); num_np = lnp->num_np; viloc = lpsc->viloc; for ( i=0; iviloc = viloc; begin_read_vld(&lpsc->viloc); BOOL bcod = read_np_mem(npwg); { SG_POINT* color = reinterpret_cast(lpsc->data); for (int u = 1; u <= npwg->nov; u++) { npwg->vertInfo[u].r = color->x; npwg->vertInfo[u].g = color->y; npwg->vertInfo[u].b = color->z; } } VI_LOCATION niloc = viloc; get_read_loc(&viloc); end_read_vld(); rezet_np_mem(&niloc, npwg, (NPTYPE)npwg->type); } } lpsc->data = NULL; return OSFALSE; } static OSCAN_COD scale_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static OSCAN_COD scale_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // void sgC3DObject::Scale(const SG_POINT& scaleIn) { SG_POINT scale = scaleIn; SCAN_CONTROL sc; init_scan(&sc); sc.user_geo_scan = scale_geo_scan; sc.user_post_scan = scale_post_scan; sc.data = &scale; o_scan(GetObjectHandle(this),&sc); PostCreate(); } #pragma argsused static OSCAN_COD scale_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { return OSTRUE; } #pragma argsused static OSCAN_COD scale_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { OSCAN_COD cod = OSTRUE; BYTE TypeFace; BYTE bIsUV; if (lpsc->type!=OBREP) return OSTRUE; TypeFace = SG_L_NP_SOFT; bIsUV = 0; if ( lpsc->breptype == FRAME ) return OSTRUE; if ( !scan_flg_np_end ) return OSTRUE; if (!lpsc->data) return OSFALSE; { lpOBJ obj; OSCAN_COD cod = OSTRUE; VI_LOCATION viloc; short i,num_np; lpLNP lnp; int num; obj = (lpOBJ)hobj; num = ((lpGEO_BREP)(obj->geo_data))->num; lnp = (lpLNP)get_elem(&vd_brep, num); get_first_np_loc( &lnp->listh, &lpsc->viloc); num_np = lnp->num_np; viloc = lpsc->viloc; for ( i=0; iviloc = viloc; begin_read_vld(&lpsc->viloc); BOOL bcod = read_np_mem(npwg); { SG_POINT* scale = reinterpret_cast(lpsc->data); for (int u = 1; u <= npwg->nov; u++) { npwg->v[u].x *= scale->x; npwg->v[u].y *= scale->y; npwg->v[u].z *= scale->z; } } VI_LOCATION niloc = viloc; get_read_loc(&viloc); end_read_vld(); rezet_np_mem(&niloc, npwg, (NPTYPE)npwg->type); } } lpsc->data = NULL; return OSFALSE; } static OSCAN_COD translate_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static OSCAN_COD translate_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // void sgC3DObject::Translate(const SG_POINT& scaleIn) { SG_POINT scale = scaleIn; SCAN_CONTROL sc; init_scan(&sc); sc.user_geo_scan = translate_geo_scan; sc.user_post_scan = translate_post_scan; sc.data = &scale; o_scan(GetObjectHandle(this),&sc); PostCreate(); } #pragma argsused static OSCAN_COD translate_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { return OSTRUE; } #pragma argsused static OSCAN_COD translate_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { OSCAN_COD cod = OSTRUE; BYTE TypeFace; BYTE bIsUV; if (lpsc->type!=OBREP) return OSTRUE; TypeFace = SG_L_NP_SOFT; bIsUV = 0; if ( lpsc->breptype == FRAME ) return OSTRUE; if ( !scan_flg_np_end ) return OSTRUE; if (!lpsc->data) return OSFALSE; { lpOBJ obj; OSCAN_COD cod = OSTRUE; VI_LOCATION viloc; short i,num_np; lpLNP lnp; int num; obj = (lpOBJ)hobj; num = ((lpGEO_BREP)(obj->geo_data))->num; lnp = (lpLNP)get_elem(&vd_brep, num); get_first_np_loc( &lnp->listh, &lpsc->viloc); num_np = lnp->num_np; viloc = lpsc->viloc; for ( i=0; iviloc = viloc; begin_read_vld(&lpsc->viloc); BOOL bcod = read_np_mem(npwg); { SG_POINT* scale = reinterpret_cast(lpsc->data); for (int u = 1; u <= npwg->nov; u++) { npwg->v[u].x += scale->x; npwg->v[u].y += scale->y; npwg->v[u].z += scale->z; } } VI_LOCATION niloc = viloc; get_read_loc(&viloc); end_read_vld(); rezet_np_mem(&niloc, npwg, (NPTYPE)npwg->type); } } lpsc->data = NULL; return OSFALSE; } static OSCAN_COD transform_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // static OSCAN_COD transform_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc); // void sgC3DObject::Transform(const sgCMatrix& matrixIn) { sgCMatrix matrix; matrix.SetMatrix(&matrixIn); SCAN_CONTROL sc; init_scan(&sc); sc.user_geo_scan = transform_geo_scan; sc.user_post_scan = transform_post_scan; sc.data = &matrix; o_scan(GetObjectHandle(this),&sc); PostCreate(); } #pragma argsused static OSCAN_COD transform_post_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { return OSTRUE; } #pragma argsused static OSCAN_COD transform_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { OSCAN_COD cod = OSTRUE; BYTE TypeFace; BYTE bIsUV; if (lpsc->type!=OBREP) return OSTRUE; TypeFace = SG_L_NP_SOFT; bIsUV = 0; if ( lpsc->breptype == FRAME ) return OSTRUE; if ( !scan_flg_np_end ) return OSTRUE; { lpOBJ obj; OSCAN_COD cod = OSTRUE; VI_LOCATION viloc; short i,num_np; lpLNP lnp; int num; obj = (lpOBJ)hobj; num = ((lpGEO_BREP)(obj->geo_data))->num; lnp = (lpLNP)get_elem(&vd_brep, num); get_first_np_loc( &lnp->listh, &lpsc->viloc); num_np = lnp->num_np; viloc = lpsc->viloc; for ( i=0; iviloc = viloc; begin_read_vld(&lpsc->viloc); BOOL bcod = read_np_mem(npwg); { sgCMatrix& m = *reinterpret_cast(lpsc->data); for (int u = 1; u <= npwg->nov; u++) { SG_POINT pt; pt.x = npwg->v[u].x; pt.y = npwg->v[u].y; pt.z = npwg->v[u].z; m.ApplyMatrixToPoint(pt); npwg->v[u].x = pt.x; npwg->v[u].y = pt.y; npwg->v[u].z = pt.z; } } VI_LOCATION niloc = viloc; get_read_loc(&viloc); end_read_vld(); rezet_np_mem(&niloc, npwg, (NPTYPE)npwg->type); } } return OSFALSE; } ///////////////////////////////////////////////////////////////////////////////////// void TriangleNormal(SG_POINT* Vert1,SG_POINT* Vert2,SG_POINT* Vert3,SG_VECTOR* N) { SG_POINT P1,P2,P3; P1.x = Vert1->x; P1.y = Vert1->y; P1.z = Vert1->z; P2.x = Vert2->x; P2.y = Vert2->y; P2.z = Vert2->z; P3.x = Vert3->x; P3.y = Vert3->y; P3.z = Vert3->z; N->x = (P2.y-P1.y)*(P3.z-P1.z) - (P2.z-P1.z)*(P3.y-P1.y); N->y = (P2.z-P1.z)*(P3.x-P1.x) - (P2.x-P1.x)*(P3.z-P1.z); N->z = (P2.x-P1.x)*(P3.y-P1.y) - (P2.y-P1.y)*(P3.x-P1.x); sgFloat cs; cs = sqrt(N->x*N->x + N->y*N->y + N->z*N->z); if ( cs < MINsgFloat*10) return; // N->x /= cs; // N->y /= cs; N->z /= cs; } /* static void FillTriangBrep() { int j, k, m,idP1,idP2,idP3; size_t all_np_ar_sz = all_np_of_brep.size(); // - triangles_of_cur_object->nTr = 0; for(size_t i = 0; inTr += all_np_of_brep[i].nTr; if(triangles_of_cur_object->nTr) { triangles_of_cur_object->allVertex = (SG_POINT*)malloc(3*triangles_of_cur_object->nTr*sizeof(SG_POINT)); triangles_of_cur_object->allNormals = (SG_VECTOR*)malloc(3*triangles_of_cur_object->nTr*sizeof(SG_VECTOR)); } // m = 0; for(size_t i = 0; iallVertex[m] = all_np_of_brep[i].pV[idP1]; triangles_of_cur_object->allVertex[m+1] = all_np_of_brep[i].pV[idP2]; triangles_of_cur_object->allVertex[m+2] = all_np_of_brep[i].pV[idP3]; // triangles_of_cur_object->allNormals[m] = all_np_of_brep[i].pN[idP1]; triangles_of_cur_object->allNormals[m+1] = all_np_of_brep[i].pN[idP2]; triangles_of_cur_object->allNormals[m+2] = all_np_of_brep[i].pN[idP3]; m += 3; } break; case SG_L_NP_SHARP: for(j = 0, k = 0; j < all_np_of_brep[i].nTr; j++, k += 3) { idP1 = all_np_of_brep[i].pTr[j].i1; idP2 = all_np_of_brep[i].pTr[j].i2; idP3 = all_np_of_brep[i].pTr[j].i3; // triangles_of_cur_object->allVertex[m] = all_np_of_brep[i].pV[idP1]; triangles_of_cur_object->allVertex[m+1] = all_np_of_brep[i].pV[idP2]; triangles_of_cur_object->allVertex[m+2] = all_np_of_brep[i].pV[idP3]; // triangles_of_cur_object->allNormals[m] = all_np_of_brep[i].pN[k]; triangles_of_cur_object->allNormals[m+1] = all_np_of_brep[i].pN[k+1]; triangles_of_cur_object->allNormals[m+2] = all_np_of_brep[i].pN[k+2]; m += 3; } break; case SG_L_NP_PLANE: for(j = 0; j < all_np_of_brep[i].nTr; j++) { SG_VECTOR N; idP1 = all_np_of_brep[i].pTr[j].i1; idP2 = all_np_of_brep[i].pTr[j].i2; idP3 = all_np_of_brep[i].pTr[j].i3; // triangles_of_cur_object->allVertex[m] = all_np_of_brep[i].pV[idP1]; triangles_of_cur_object->allVertex[m+1] = all_np_of_brep[i].pV[idP2]; triangles_of_cur_object->allVertex[m+2] = all_np_of_brep[i].pV[idP3]; TriangleNormal(&triangles_of_cur_object->allVertex[m], &triangles_of_cur_object->allVertex[m+1], &triangles_of_cur_object->allVertex[m+2],&N); triangles_of_cur_object->allNormals[m] = N; triangles_of_cur_object->allNormals[m+1] = N; triangles_of_cur_object->allNormals[m+2] = N; m += 3; } break; } } // // - if(IsMatrixMirror()) { for(m = 0; m < 3*triangles_of_cur_object->nTr; m += 3) { triangles_of_cur_object->allNormals[m].x = -triangles_of_cur_object->allNormals[m].x; triangles_of_cur_object->allNormals[m].y = -triangles_of_cur_object->allNormals[m].y; triangles_of_cur_object->allNormals[m].z = -triangles_of_cur_object->allNormals[m].z; triangles_of_cur_object->allNormals[m+1].x = -triangles_of_cur_object->allNormals[m+1].x; triangles_of_cur_object->allNormals[m+1].y = -triangles_of_cur_object->allNormals[m+1].y; triangles_of_cur_object->allNormals[m+1].z = -triangles_of_cur_object->allNormals[m+1].z; triangles_of_cur_object->allNormals[m+2].x = -triangles_of_cur_object->allNormals[m+2].x; triangles_of_cur_object->allNormals[m+2].y = -triangles_of_cur_object->allNormals[m+2].y; triangles_of_cur_object->allNormals[m+2].z = -triangles_of_cur_object->allNormals[m+2].z; } } } */ void MultVectMatr(sgFloat* t,lpD_POINT v,lpD_POINT vp) { sgFloat vx, vy, vz; vx = v->x; vy = v->y; vz = v->z; vp->x = vx*t[0] + vy*t[4] + vz*t[8] + t[12]; vp->y = vx*t[1] + vy*t[5] + vz*t[9] + t[13]; vp->z = vx*t[2] + vy*t[6] + vz*t[10] + t[14]; } static BOOL IsMatrixMirror() { lpOBJ obj = (lpOBJ)localObjForMirrorCheck; MATR tmp_matr; memcpy(tmp_matr,((lpGEO_BREP)(obj->geo_data))->matr,sizeof(MATR)); D_POINT p0={0.0, 0.0, 0.0}; D_POINT p1={1.0, 0.0, 0.0}; D_POINT p2={0.0, 1.0, 0.0}; D_POINT p3={0.0, 0.0, 1.0}; MultVectMatr(tmp_matr,&p0,&p0); MultVectMatr(tmp_matr,&p1,&p1); MultVectMatr(tmp_matr,&p2,&p2); MultVectMatr(tmp_matr,&p3,&p3); // - . p1.x=p1.x-p0.x; p1.y=p1.y-p0.y; p1.z=p1.z-p0.z; p2.x=p2.x-p0.x; p2.y=p2.y-p0.y; p2.z=p2.z-p0.z; p3.x=p3.x-p0.x; p3.y=p3.y-p0.y; p3.z=p3.z-p0.z; dvector_product(&p1,&p2, &p1); // p1*p3 if((p1.x*p3.x + p1.y*p3.y + p1.z*p3.z) < 0) return TRUE; return FALSE; } const SG_ALL_TRIANGLES* sgC3DObject::GetTriangles() const {return m_triangles;} static OSCAN_COD edgesBr_pre_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { sgC3DObject* tmpObj = static_cast(lpsc->data); if(lpsc->type == OBREP) { // if ( lpsc->breptype == BODY ) Set3DObjectType(tmpObj, SG_BODY); else /*if ( lpsc->breptype == FRAME ) Set3DObjectType(tmpObj, SG_FRAME); else*/ Set3DObjectType(tmpObj, SG_SURFACE); } // return OSTRUE; } static OSCAN_COD edgesBr_geo_scan(hOBJ hobj, lpSCAN_CONTROL lpsc) { register short i; OSCAN_COD cod = OSTRUE; NP_STR str; if (lpsc->type!=OBREP) return OSTRUE; if ( scan_flg_np_begin ) if ( !np_init_list(&list_str) ) return OSFALSE; npwg->type = TNPW; if ( !np_cplane(npwg) ) { cod = OSFALSE; // goto end; np_end_of_put(&list_str,NP_CANCEL,0,NULL); return cod; } if ( !(np_put(npwg,&list_str)) ) { cod = OSFALSE; //goto end; np_end_of_put(&list_str,NP_CANCEL,0,NULL); return cod; } if ( !scan_flg_np_end ) return OSTRUE; sgCBRep* tmpBRep = (static_cast(lpsc->data))->GetBRep(); AllocMemoryForBRepPiecesInBRep(tmpBRep, list_str.number_all); // FILE* fl = fopen("D://brep.ooo","w+"); for (i = 0; i < list_str.number_all; i++) { read_elem(&list_str.vdim, i, &str); #ifndef NEW_TRIANGULATION read_np(&list_str.bnp, str.hnp, npwg); #else lpNPW tmpNPW = GetNPWFromBRepPiece(tmpBRep->GetPiece(i)); read_np(&list_str.bnp, str.hnp, tmpNPW); /*fprintf(fl,"------ New BREP piece ------ number %i -------\n",i); fprintf(fl," Vertexes Count: %i\n", tmpNPW->nov); fprintf(fl," Edges Count: %i\n", tmpNPW->noe); fprintf(fl," Faces Count: %i\n", tmpNPW->nof); fprintf(fl," Cicles Count: %i\n", tmpNPW->noc); fprintf(fl," ------ Vertexes -----\n"); for (short jj=0;jjnov+5;jj++) { fprintf(fl," %3i : X=%10f Y=%10f Z=%10f\n", jj,tmpNPW->v[jj].x,tmpNPW->v[jj].y,tmpNPW->v[jj].z); } fprintf(fl," ------ Edges -----\n"); for (short jj=0;jjnoe+5;jj++) { fprintf(fl," %3i : Begin=%5i End=%5i Type=%5i\n", jj,tmpNPW->efr[jj].bv , tmpNPW->efr[jj].ev, tmpNPW->efr[jj].el); } fprintf(fl," ------ Faces -----\n"); for (short jj=0;jjnof+5;jj++) { fprintf(fl," %3i : Begin contour=%5i Type=%5i\n", jj,tmpNPW->f[jj].fc , tmpNPW->f[jj].fl); } fprintf(fl," ------ Cicles -----\n"); for (short jj=0;jjnoc+5;jj++) { fprintf(fl," %3i : First edge=%5i Next contour=%5i\n", jj,tmpNPW->c[jj].fe , tmpNPW->c[jj].nc); }*/ #endif TMP_STRUCT_FOR_BREP_PIECES_SETTING tmpSFBPS; tmpSFBPS.br = tmpBRep; tmpSFBPS.ii = i; #ifndef NEW_TRIANGULATION Set_i_BRepPiece(&tmpSFBPS,npwg); #else Set_i_BRepPiece(&tmpSFBPS,tmpNPW); #endif } /* fflush(fl); fclose(fl);*/ //end: np_end_of_put(&list_str,NP_CANCEL,0,NULL); return cod; } void sgC3DObject::SetMaterial(const SG_MATERIAL& newMat) { if (!m_material) m_material = new SG_MATERIAL; if (memcmp(m_material, &newMat, sizeof(SG_MATERIAL))!=0) { memcpy(m_material,&newMat,sizeof(SG_MATERIAL)); sgFloat TmpAttr = m_material->MaterialIndex; set_hobj_attr_value(id_Material, GetObjectHandle(this),&TmpAttr); set_hobj_attr_value(id_TextureScaleU, GetObjectHandle(this), &m_material->TextureScaleU); set_hobj_attr_value(id_TextureScaleV, GetObjectHandle(this), &m_material->TextureScaleV); set_hobj_attr_value(id_TextureShiftU, GetObjectHandle(this), &m_material->TextureShiftU); set_hobj_attr_value(id_TextureShiftV, GetObjectHandle(this), &m_material->TextureShiftV); set_hobj_attr_value(id_TextureAngle, GetObjectHandle(this), &m_material->TextureAngle); TmpAttr = (m_material->TextureSmooth)?1.0:0.0; set_hobj_attr_value(id_Smooth, GetObjectHandle(this),&TmpAttr); TmpAttr = (sgFloat)m_material->MixColorType; set_hobj_attr_value(id_MixColor, GetObjectHandle(this),&TmpAttr); TmpAttr = (sgFloat)m_material->TextureUVType; set_hobj_attr_value(id_UVType, GetObjectHandle(this),&TmpAttr); TmpAttr = (m_material->TextureMult)?1.0:0.0; set_hobj_attr_value(id_TextureMult, GetObjectHandle(this),&TmpAttr); CalcUV(); } } const SG_MATERIAL* sgC3DObject::GetMaterial() { if (m_material) return m_material; sgFloat nMat=-1.0; get_hobj_attr_value(id_Material, GetObjectHandle(this), &nMat); if (nMat>=0) { m_material = new SG_MATERIAL; m_material->MaterialIndex = static_cast(nMat); get_hobj_attr_value(id_TextureScaleU, GetObjectHandle(this), &m_material->TextureScaleU); get_hobj_attr_value(id_TextureScaleV, GetObjectHandle(this), &m_material->TextureScaleV); get_hobj_attr_value(id_TextureShiftU, GetObjectHandle(this), &m_material->TextureShiftU); get_hobj_attr_value(id_TextureShiftV, GetObjectHandle(this), &m_material->TextureShiftV); get_hobj_attr_value(id_TextureAngle, GetObjectHandle(this), &m_material->TextureAngle); sgFloat TmpAttr = 0.0; get_hobj_attr_value(id_Smooth, GetObjectHandle(this), &TmpAttr); m_material->TextureSmooth = (TmpAttr>0.001); get_hobj_attr_value(id_MixColor, GetObjectHandle(this), &TmpAttr); switch((int)TmpAttr) { case 1: m_material->MixColorType = SG_MODULATE_MIX_TYPE; break; case 2: m_material->MixColorType = SG_BLEND_MIX_TYPE; break; default: m_material->MixColorType = SG_REPLACE_MIX_TYPE; break; } get_hobj_attr_value(id_UVType, GetObjectHandle(this), &TmpAttr); switch((int)TmpAttr) { case 2: m_material->TextureUVType = SG_SPHERIC_UV_TYPE; break; case 3: m_material->TextureUVType = SG_CYLINDER_UV_TYPE; break; default: m_material->TextureUVType = SG_CUBE_UV_TYPE; break; } get_hobj_attr_value(id_TextureMult, GetObjectHandle(this), &TmpAttr); m_material->TextureMult = (TmpAttr>0.001); if (m_triangles && m_triangles->allUV==NULL) CalcUV(); } return m_material; } bool sgC3DObject::CalculateOptimalUV(sgFloat& optU, sgFloat& optV) { sgFloat Sxz,Syz,Sxy,Smax; sgFloat MaxU,MaxV/*,kScale*/; Smax = 0; Sxz = fabs((m_max.x-m_min.x)*(m_max.z-m_min.z)); if(Sxz > Smax) { Smax = Sxz; MaxU = m_max.x-m_min.x; MaxV = m_max.z-m_min.z; } Syz = fabs((m_max.y-m_min.y)*(m_max.z-m_min.z)); if(Syz > Smax) { Smax = Syz; MaxU = m_max.y-m_min.y; MaxV = m_max.z-m_min.z; } Sxy = fabs((m_max.x-m_min.x)*(m_max.y-m_min.y)); if(Sxy > Smax) { Smax = Sxz; MaxU = m_max.x-m_min.x; MaxV = m_max.y-m_min.y; } // , // !!!!!! if(fabs(GetWorldMatrixData()[10]) > 1.0) { sgFloat kScale = fabs(GetWorldMatrixData()[10]); MaxU /= kScale; MaxV /= kScale; } // // sgFloat lScaleU,lScaleV; lScaleU = lScaleV = 1.0; //if(m_lpTmpHdr->nIdxMat) /* if(true) { MAT_ITEM TmpItem; CString NameItem; int i,Total; long SelItem; // Total = m_lpMatLib->GetTotalMaterial(); SelItem = c_list.GetCurSel(); if(SelItem == LB_ERR) return ; c_list.GetText(SelItem,NameItem); // for(i = 0; i < Total; i++) { if(!strcmp((LPCSTR)NameItem,m_lpMatLib->m_aMatIdx.GetAt(i).szName)) break; } //if(m_lpMatLib->LoadMatItem(m_lpTmpHdr->nIdxMat-1,&TmpMat)) if(m_lpMatLib->LoadMatItem(i,&TmpItem)) { if(fabs(TmpItem.ScaleU) > 0) lScaleU = TmpItem.ScaleU; if(fabs(TmpItem.ScaleV) > 0) lScaleV = TmpItem.ScaleV; } }*/ optU = (fabs(MaxU/lScaleU)); optV = (fabs(MaxV/lScaleV)); return true; } void sgC3DObject::CalcUV() { assert(m_triangles); assert(m_material); assert(m_triangles->allNormals); assert(m_triangles->allVertex); if (m_triangles==NULL || m_material==NULL || m_triangles->allNormals==NULL || m_triangles->allVertex==NULL) return; if (m_triangles->allUV==NULL) m_triangles->allUV = (sgFloat*)malloc(2*3*m_triangles->nTr*sizeof(sgFloat)); switch(m_material->TextureUVType) { case SG_CYLINDER_UV_TYPE: { SG_POINT P1,P2,P3; sgFloat radius; sgFloat alpha; int j = 0; for(int i = 0; i < m_triangles->nTr; i += 1) { P1.x = m_triangles->allVertex[i*3].x; P1.y = m_triangles->allVertex[i*3].y; P1.z = m_triangles->allVertex[i*3].z; radius = sqrt (P1.x*P1.x+P1.y*P1.y); alpha = asin(P1.y/radius); m_triangles->allUV[j] = (alpha+M_PI/2)/(2*M_PI)*360; m_triangles->allUV[j+1] = P1.z; j += 2; P2.x = m_triangles->allVertex[i*3+1].x; P2.y = m_triangles->allVertex[i*3+1].y; P2.z = m_triangles->allVertex[i*3+1].z; radius = sqrt (P2.x*P2.x+P2.y*P2.y); alpha = asin(P2.y/radius); m_triangles->allUV[j] = (alpha+M_PI/2)/(2*M_PI)*360;//U m_triangles->allUV[j+1] = P2.z; // V j += 2; P3.x = m_triangles->allVertex[i*3+2].x; P3.y = m_triangles->allVertex[i*3+2].y; P3.z = m_triangles->allVertex[i*3+2].z; radius = sqrt (P3.x*P3.x+P3.y*P3.y); alpha = asin(P3.y/radius); m_triangles->allUV[j] = (alpha+M_PI/2)/(2*M_PI)*360; m_triangles->allUV[j+1] = P3.z; j += 2; } } break; case SG_SPHERIC_UV_TYPE: { SG_POINT P1,P2,P3; sgFloat radius; sgFloat alpha,beta; int j = 0; for(int i = 0; i < (m_triangles->nTr); i += 1) { P1.x = m_triangles->allVertex[i*3].x; P1.y = m_triangles->allVertex[i*3].y; P1.z = m_triangles->allVertex[i*3].z; radius = sqrt (P1.x*P1.x + P1.y*P1.y + P1.z*P1.z); alpha = asin(P1.z/radius); beta = acos(P1.y/sqrt(P1.x*P1.x+P1.y*P1.y)); m_triangles->allUV[j] = alpha*180; m_triangles->allUV[j+1] = beta*180; j += 2; P2.x = m_triangles->allVertex[i*3+1].x; P2.y = m_triangles->allVertex[i*3+1].y; P2.z = m_triangles->allVertex[i*3+1].z; radius = sqrt (P2.x*P2.x + P2.y*P2.y + P2.z*P2.z); alpha = asin(P2.z/radius); beta = acos(P2.y/sqrt(P2.x*P2.x+P2.y*P2.y)); m_triangles->allUV[j] = alpha*180; m_triangles->allUV[j+1] = beta*180; j += 2; P3.x = m_triangles->allVertex[i*3+2].x; P3.y = m_triangles->allVertex[i*3+2].y; P3.z = m_triangles->allVertex[i*3+2].z; radius = sqrt (P3.x*P3.x+P3.y*P3.y + P3.z*P3.z); alpha = asin(P3.z/radius); beta = acos(P3.y/sqrt(P3.x*P3.x+P3.y*P3.y)); m_triangles->allUV[j] = alpha*180; m_triangles->allUV[j+1] = beta*180; j += 2; } } break; default: { int i; SG_POINT P1,P2,P3; int Type; int j = 0; for(i = 0; i < (m_triangles->nTr); i += 1) { if ( (fabs(m_triangles->allNormals[i*3].x) > fabs(m_triangles->allNormals[i*3].y)) && (fabs(m_triangles->allNormals[i*3].x) > fabs(m_triangles->allNormals[i*3].z)) ){Type = 0; }else{ if ( (fabs(m_triangles->allNormals[i*3].y) > fabs(m_triangles->allNormals[i*3].z))) {Type = 1;} else {Type = 2;} } P1.x = m_triangles->allVertex[i*3].x; P1.y = m_triangles->allVertex[i*3].y; P1.z = m_triangles->allVertex[i*3].z; if(Type == 0){ m_triangles->allUV[j] = P1.z; m_triangles->allUV[j+1] = -P1.y; } else if(Type ==1) { m_triangles->allUV[j] = P1.x; m_triangles->allUV[j+1] = P1.z; }else { m_triangles->allUV[j] = P1.x; m_triangles->allUV[j+1] = -P1.y; } j+=2; P2.x = m_triangles->allVertex[i*3+1].x; P2.y = m_triangles->allVertex[i*3+1].y; P2.z = m_triangles->allVertex[i*3+1].z; if(Type == 0) { m_triangles->allUV[j] = P2.z; m_triangles->allUV[j+1] = -P2.y; } else if(Type ==1) { m_triangles->allUV[j] = P2.x; m_triangles->allUV[j+1] = P2.z; } else { m_triangles->allUV[j] = P2.x; m_triangles->allUV[j+1] = -P2.y; } j+=2; P3.x = m_triangles->allVertex[i*3+2].x; P3.y = m_triangles->allVertex[i*3+2].y; P3.z = m_triangles->allVertex[i*3+2].z; if(Type == 0) { m_triangles->allUV[j] = P3.z; m_triangles->allUV[j+1] = -P3.y; } else if(Type ==1) { m_triangles->allUV[j] = P3.x; m_triangles->allUV[j+1] = P3.z; } else { m_triangles->allUV[j] = P3.x; m_triangles->allUV[j+1] = -P3.y; } j+=2; } } } } sgFloat sgC3DObject::GetVolume() { if (m_objectType!=SG_BODY) return 0.0; BOOL flgs[X_NUM]; sgFloat vals[X_NUM]; for( int i=0; i