From: skl Date: Wed, 25 Jan 2006 09:09:49 +0000 (+0000) Subject: Changes for working with quadratic elements X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c94984b86d2507dadaa5c73c345631cd551e7591;p=modules%2Fsmesh.git Changes for working with quadratic elements --- diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 1fe2f2dd8..34f071850 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -69,7 +69,14 @@ module SMESH MOVE_NODE, CHANGE_ELEMENT_NODES, CHANGE_POLYHEDRON_NODES, - RENUMBER + RENUMBER, + ADD_QUADEDGE, + ADD_QUADTRIANGLE, + ADD_QUADQUADRANGLE, + ADD_QUADTETRAHEDRON, + ADD_QUADPYRAMID, + ADD_QUADPENTAHEDRON, + ADD_QUADHEXAHEDRON }; struct log_block @@ -514,6 +521,8 @@ module SMESH boolean AddFace(in long_array IDsOfNodes); + boolean AddPolygonalFace(in long_array IdsOfNodes); + boolean AddVolume(in long_array IDsOfNodes); /*! diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index b9d84175f..61f525c9b 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -450,35 +450,20 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() for(int iElem = 0; iElem < aNbElems; iElem++){ TInt aNbNodes = -1; switch(aGeom){ - case eSEG2: - case eSEG3: - aNbNodes = 2; - break; - case eTRIA3: - case eTRIA6: - aNbNodes = 3; - break; - break; - case eQUAD4: - case eQUAD8: - aNbNodes = 4; - break; - case eTETRA4: - case eTETRA10: - aNbNodes = 4; - break; - case ePYRA5: - case ePYRA13: - aNbNodes = 5; - break; - case ePENTA6: - case ePENTA15: - aNbNodes = 6; - break; - case eHEXA8: - case eHEXA20: - aNbNodes = 8; - break; + case eSEG2: aNbNodes = 2; break; + case eSEG3: aNbNodes = 3; break; + case eTRIA3: aNbNodes = 3; break; + case eTRIA6: aNbNodes = 6; break; + case eQUAD4: aNbNodes = 4; break; + case eQUAD8: aNbNodes = 8; break; + case eTETRA4: aNbNodes = 4; break; + case eTETRA10: aNbNodes = 10; break; + case ePYRA5: aNbNodes = 5; break; + case ePYRA13: aNbNodes = 13; break; + case ePENTA6: aNbNodes = 6; break; + case ePENTA15: aNbNodes = 15; break; + case eHEXA8: aNbNodes = 8; break; + case eHEXA20: aNbNodes = 20; break; } vector aNodeIds(aNbNodes); bool anIsValidConnect = false; @@ -519,7 +504,6 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() // << aCellInfo->GetElemNum(iElem)); switch(aGeom){ case eSEG2: - case eSEG3: if(anIsElemNum) anElement = myMesh->AddEdgeWithID(aNodeIds[0], aNodeIds[1], @@ -530,8 +514,20 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case eSEG3: + if(anIsElemNum) + anElement = myMesh->AddEdgeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2])); + isRenum = anIsElemNum; + } + break; case eTRIA3: - case eTRIA6: aNbNodes = 3; if(anIsElemNum) anElement = myMesh->AddFaceWithID(aNodeIds[0], @@ -545,15 +541,29 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case eTRIA6: + aNbNodes = 6; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5])); + isRenum = anIsElemNum; + } + break; case eQUAD4: - case eQUAD8: aNbNodes = 4; // There is some differnce between SMDS and MED if(anIsElemNum) - anElement = myMesh->AddFaceWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], aCellInfo->GetElemNum(iElem)); if (!anElement) { anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), @@ -563,14 +573,31 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case eQUAD8: + aNbNodes = 8; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7])); + isRenum = anIsElemNum; + } + break; case eTETRA4: - case eTETRA10: aNbNodes = 4; if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], aCellInfo->GetElemNum(iElem)); if (!anElement) { anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), @@ -580,15 +607,35 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case eTETRA10: + aNbNodes = 10; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9])); + isRenum = anIsElemNum; + } + break; case ePYRA5: - case ePYRA13: aNbNodes = 5; // There is some differnce between SMDS and MED if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], aNodeIds[4], aCellInfo->GetElemNum(iElem)); if (!anElement) { @@ -600,8 +647,36 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case ePYRA13: + aNbNodes = 13; + // There is some differnce between SMDS and MED + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12])); + isRenum = anIsElemNum; + } + break; case ePENTA6: - case ePENTA15: aNbNodes = 6; if(anIsElemNum) anElement = myMesh->AddVolumeWithID(aNodeIds[0], @@ -621,8 +696,38 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case ePENTA15: + aNbNodes = 15; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], aNodeIds[13], + aNodeIds[14], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12]), + FindNode(myMesh,aNodeIds[13]), + FindNode(myMesh,aNodeIds[14])); + isRenum = anIsElemNum; + } + break; case eHEXA8: - case eHEXA20: aNbNodes = 8; if(anIsElemNum) anElement = myMesh->AddVolumeWithID(aNodeIds[0], @@ -646,11 +751,51 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case eHEXA20: + aNbNodes = 20; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], aNodeIds[13], + aNodeIds[14], aNodeIds[15], + aNodeIds[16], aNodeIds[17], + aNodeIds[18], aNodeIds[19], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12]), + FindNode(myMesh,aNodeIds[13]), + FindNode(myMesh,aNodeIds[14]), + FindNode(myMesh,aNodeIds[15]), + FindNode(myMesh,aNodeIds[16]), + FindNode(myMesh,aNodeIds[17]), + FindNode(myMesh,aNodeIds[18]), + FindNode(myMesh,aNodeIds[19])); + isRenum = anIsElemNum; + } + break; } - }catch(const std::exception& exc){ + } + catch(const std::exception& exc){ //INFOS("Follow exception was cought:\n\t"<AddElement(anElement); aFamily->SetType(anElement->GetType()); @@ -678,10 +822,12 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() break; } } - }catch(const std::exception& exc){ + } + catch(const std::exception& exc){ INFOS("Follow exception was cought:\n\t"<edgesIterator(); - TInt aNbConnectivity = MED::GetNbNodes(eSEG2); - MED::TIntVector anElemNums(aNbElems); - MED::TIntVector aFamilyNums(aNbElems); - MED::TIntVector aConnectivity(aNbElems*aNbConnectivity); - for(TInt iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){ +// TInt aNbConnectivity = MED::GetNbNodes(eSEG2); +// MED::TIntVector anElemNums(aNbElems); +// MED::TIntVector aFamilyNums(aNbElems); +// MED::TIntVector aConnectivity(aNbElems*aNbConnectivity); + + TInt aNbSeg2Conn = MED::GetNbNodes(eSEG2); + MED::TIntVector aSeg2ElemNums(aNbElems); + MED::TIntVector aSeg2FamilyNums(aNbElems); + MED::TIntVector aSeg2Conn(aNbElems*aNbSeg2Conn); + + TInt aNbSeg3Conn = MED::GetNbNodes(eSEG3); + MED::TIntVector aSeg3ElemNums(aNbElems); + MED::TIntVector aSeg3FamilyNums(aNbElems); + MED::TIntVector aSeg3Conn(aNbElems*aNbSeg3Conn); + + //for(TInt iElem = 0, Conn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){ + for(TInt iElem = 0; anIter->more(); iElem++) { const SMDS_MeshEdge* anElem = anIter->next(); + TInt aNbNodes = anElem->NbNodes(); SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); - for(TInt iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){ + + TInt aNbConnectivity; + MED::TIntVector* anElemNums; + MED::TIntVector* aFamilyNums; + MED::TIntVector* aConnectivity; + switch(aNbNodes){ + case 2: + aNbConnectivity = aNbSeg2Conn; + anElemNums = &aSeg2ElemNums; + aFamilyNums = &aSeg2FamilyNums; + aConnectivity = &aSeg2Conn; + break; + case 3: + aNbConnectivity = aNbSeg3Conn; + anElemNums = &aSeg3ElemNums; + aFamilyNums = &aSeg3FamilyNums; + aConnectivity = &aSeg3Conn; + break; + default: + break; + } + + MED::TIntVector aVector(aNbNodes); + for(TInt iNode = 0; aNodesIter->more(); iNode++){ const SMDS_MeshElement* aNode = aNodesIter->next(); #ifdef _EDF_NODE_IDS_ - aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()]; + aVector[iNode] = aNodeIdMap[aNode->GetID()]; #else - aConnectivity[iConn+iNode] = aNode->GetID(); + aVector[iNode] = aNode->GetID(); #endif } - anElemNums[iElem] = anElem->GetID(); + + TInt aSize = aConnectivity->size(); + aConnectivity->resize(aSize+aNbConnectivity); + // There is some differences between SMDS and MED in cells mapping + for(TInt iNode = 0; iNode < aNbNodes; iNode++) + (*aConnectivity)[aSize+iNode] = aVector[iNode]; + + anElemNums->push_back(anElem->GetID()); if (anElemFamMap.find(anElem) != anElemFamMap.end()) - aFamilyNums[iElem] = anElemFamMap[anElem]; + aFamilyNums->push_back(anElemFamMap[anElem]); else - aFamilyNums[iElem] = myEdgesDefaultFamilyId; + aFamilyNums->push_back(myFacesDefaultFamilyId); + } - PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo, - SMDS_MED_ENTITY, - eSEG2, - SMDS_MED_CONNECTIVITY, - aConnectivity, - aFamilyNums, - anElemNums); - myMed->SetCellInfo(aCellInfo); + if(TInt aNbElems = aSeg2ElemNums.size()){ + PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo, + SMDS_MED_ENTITY, + eSEG2, + SMDS_MED_CONNECTIVITY, + aSeg2Conn, + aSeg2FamilyNums, + aSeg2ElemNums); + myMed->SetCellInfo(aCellInfo); + } + if(TInt aNbElems = aSeg3ElemNums.size()){ + PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo, + SMDS_MED_ENTITY, + eSEG3, + SMDS_MED_CONNECTIVITY, + aSeg3Conn, + aSeg3FamilyNums, + aSeg3ElemNums); + myMed->SetCellInfo(aCellInfo); + } } // Storing SMDS Faces @@ -442,6 +498,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() MED::TIntVector aTriaConn; aTriaConn.reserve(aNbElems*aNbTriaConn); + TInt aNbTria6Conn = MED::GetNbNodes(eTRIA6); + MED::TIntVector anTria6ElemNums; + anTria6ElemNums.reserve(aNbElems); + MED::TIntVector aTria6FamilyNums; + aTria6FamilyNums.reserve(aNbElems); + MED::TIntVector aTria6Conn; + aTria6Conn.reserve(aNbElems*aNbTria6Conn); + TInt aNbQuadConn = MED::GetNbNodes(eQUAD4); MED::TIntVector aQuadElemNums; aQuadElemNums.reserve(aNbElems); @@ -450,6 +514,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() MED::TIntVector aQuadConn; aQuadConn.reserve(aNbElems*aNbQuadConn); + TInt aNbQuad8Conn = MED::GetNbNodes(eQUAD8); + MED::TIntVector aQuad8ElemNums; + aQuad8ElemNums.reserve(aNbElems); + MED::TIntVector aQuad8FamilyNums; + aQuad8FamilyNums.reserve(aNbElems); + MED::TIntVector aQuad8Conn; + aQuad8Conn.reserve(aNbElems*aNbQuad8Conn); + MED::TIntVector aPolygoneElemNums; aPolygoneElemNums.reserve(aNbElems); MED::TIntVector aPolygoneInds; @@ -473,7 +545,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() anElemNums = &aPolygoneElemNums; aFamilyNums = &aPolygoneFamilyNums; aConnectivity = &aPolygoneConn; - } else { + } + else { switch(aNbNodes){ case 3: aNbConnectivity = aNbTriaConn; @@ -487,6 +560,18 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() aFamilyNums = &aQuadFamilyNums; aConnectivity = &aQuadConn; break; + case 6: + aNbConnectivity = aNbTria6Conn; + anElemNums = &anTria6ElemNums; + aFamilyNums = &aTria6FamilyNums; + aConnectivity = &aTria6Conn; + break; + case 8: + aNbConnectivity = aNbQuad8Conn; + anElemNums = &aQuad8ElemNums; + aFamilyNums = &aQuad8FamilyNums; + aConnectivity = &aQuad8Conn; + break; default: break; } @@ -550,6 +635,28 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() MESSAGE("Perform - anEntity = "<first; const TRecord& aRec = anIter->second; - if(IsBeam(aRec.fe_descriptor_id)){ - anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], - aRec.node_labels[1], - aLabel); - }else if(IsFace(aRec.fe_descriptor_id)){ + if(IsBeam(aRec.fe_descriptor_id)) { + if(aRec.fe_descriptor_id == 11) { + // edge with two nodes + anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], + aRec.node_labels[1], + aLabel); + } + else { + // quadratic edge (with 3 nodes) + anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aLabel); + } + } + else if(IsFace(aRec.fe_descriptor_id)) { switch(aRec.fe_descriptor_id){ case 71: // TRI3 case 72: @@ -76,18 +87,31 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() case 41: // Plane Stress Linear Triangle - TRI3 case 91: // Thin Shell Linear Triangle - TRI3 + anElement = myMesh->AddFaceWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aLabel); + break; case 42: // Plane Stress Quadratic Triangle - TRI6 case 92: // Thin Shell Quadratic Triangle - TRI6 - anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], + aRec.node_labels[3], + aRec.node_labels[4], + aRec.node_labels[5], aLabel); break; case 44: // Plane Stress Linear Quadrilateral - QUAD4 case 94: // Thin Shell Linear Quadrilateral - QUAD4 + anElement = myMesh->AddFaceWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aRec.node_labels[3], + aLabel); + break; case 45: // Plane Stress Quadratic Quadrilateral - QUAD8 case 95: // Thin Shell Quadratic Quadrilateral - QUAD8 @@ -95,24 +119,40 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.node_labels[1], aRec.node_labels[2], aRec.node_labels[3], + aRec.node_labels[4], + aRec.node_labels[5], + aRec.node_labels[6], + aRec.node_labels[7], aLabel); break; } - }else if(IsVolume(aRec.fe_descriptor_id)){ + } + else if(IsVolume(aRec.fe_descriptor_id)){ switch(aRec.fe_descriptor_id){ case 111: // Solid Linear Tetrahedron - TET4 + anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], + aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[3], + aLabel); + break; + case 118: // Solid Quadratic Tetrahedron - TET10 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], aRec.node_labels[3], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[4], + aRec.node_labels[7], + aRec.node_labels[9], + aRec.node_labels[8], aLabel); break; case 112: // Solid Linear Prism - PRISM6 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], @@ -123,13 +163,21 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() break; case 113: // Solid Quadratic Prism - PRISM15 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], - aRec.node_labels[4], aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[3], + aRec.node_labels[5], + aRec.node_labels[4], + aRec.node_labels[8], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[11], + aRec.node_labels[10], aRec.node_labels[9], + aRec.node_labels[12], + aRec.node_labels[14], aRec.node_labels[13], - aRec.node_labels[11], aLabel); break; @@ -146,26 +194,57 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() break; case 116: // Solid Quadratic Brick - HEX20 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], - aRec.node_labels[6], - aRec.node_labels[4], + aRec.node_labels[3], aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[4], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[11], + aRec.node_labels[10], + aRec.node_labels[9], + aRec.node_labels[8], + aRec.node_labels[15], + aRec.node_labels[14], + aRec.node_labels[13], aRec.node_labels[12], - aRec.node_labels[18], aRec.node_labels[16], - aRec.node_labels[14], + aRec.node_labels[19], + aRec.node_labels[18], + aRec.node_labels[17], + aLabel); + break; + + case 114: // pyramid of 13 nodes (quadratic) - PIRA13 + anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], + aRec.node_labels[3], + aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[4], + aRec.node_labels[8], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[9], + aRec.node_labels[12], + aRec.node_labels[11], + aRec.node_labels[10], aLabel); break; + } } if(!anElement) MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<next(); aRec.node_labels.push_back(aNode->GetID()); } - aRec.fe_descriptor_id = 11; + if(aNbNodes==2) + aRec.fe_descriptor_id = 11; + else + aRec.fe_descriptor_id = 21; aDataSet2412.insert(TDataSet::value_type(aLabel,aRec)); } MESSAGE("Perform - aDataSet2412.size() = "<RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_POLYGON); aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); my3DActor = SMESH_DeviceActor::New(); my3DActor->SetUserMatrix(aMatrix); @@ -163,6 +165,8 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_WEDGE); aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); //Definition 1D divice of the actor @@ -184,6 +188,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter = my1DActor->GetExtractUnstructuredGrid(); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); my1DProp = vtkProperty::New(); my1DProp->DeepCopy(myEdgeProp); @@ -209,6 +214,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter = my1DExtActor->GetExtractUnstructuredGrid(); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); //Definition 0D divice of the actor @@ -1012,6 +1018,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ if(myEntityMode & eEdges){ if (MYDEBUG) MESSAGE("EDGES"); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); } if(myEntityMode & eFaces){ @@ -1019,6 +1026,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ aFilter->RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_POLYGON); aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); } if(myEntityMode & eVolumes){ @@ -1028,6 +1037,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_WEDGE); aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); } aFilter->Update(); diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 885ee3de3..db595bc46 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -71,18 +71,27 @@ static int MYDEBUGWITHFILES = 0; namespace{ + //======================================================================= + //function : FindNode + //======================================================================= inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){ if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem; EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<FindElement(theId)) return anElem; EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<AddFaceWithID(anIndexes[anIndexId+1], anIndexes[anIndexId+2], @@ -140,6 +155,9 @@ namespace{ } + //======================================================================= + //function : AddQuadsWithID + //======================================================================= inline void AddQuadsWithID(SMDS_Mesh* theMesh, SMESH::log_array_var theSeq, CORBA::Long theId) @@ -147,7 +165,7 @@ namespace{ const SMESH::long_array& anIndexes = theSeq[theId].indexes; CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; if(5*aNbElems != anIndexes.length()) - EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()"); + EXCEPTION(runtime_error,"AddQuadsWithID - 4*aNbElems != anIndexes.length()"); for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){ SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1], anIndexes[anIndexId+2], @@ -160,6 +178,9 @@ namespace{ } + //======================================================================= + //function : AddPolygonsWithID + //======================================================================= inline void AddPolygonsWithID(SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) @@ -184,6 +205,9 @@ namespace{ } + //======================================================================= + //function : AddTetrasWithID + //======================================================================= inline void AddTetrasWithID(SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) @@ -191,7 +215,7 @@ namespace{ const SMESH::long_array& anIndexes = theSeq[theId].indexes; CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; if(5*aNbElems != anIndexes.length()) - EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()"); + EXCEPTION(runtime_error,"AddTetrasWithID - 5*aNbElems != anIndexes.length()"); for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1], anIndexes[anIndexId+2], @@ -204,6 +228,9 @@ namespace{ } + //======================================================================= + //function : AddPiramidsWithID + //======================================================================= inline void AddPiramidsWithID(SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) @@ -211,7 +238,7 @@ namespace{ const SMESH::long_array& anIndexes = theSeq[theId].indexes; CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; if(6*aNbElems != anIndexes.length()) - EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()"); + EXCEPTION(runtime_error,"AddPiramidsWithID - 6*aNbElems != anIndexes.length()"); for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1], anIndexes[anIndexId+2], @@ -225,6 +252,9 @@ namespace{ } + //======================================================================= + //function : AddPrismsWithID + //======================================================================= inline void AddPrismsWithID(SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) @@ -232,7 +262,7 @@ namespace{ const SMESH::long_array& anIndexes = theSeq[theId].indexes; CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; if(7*aNbElems != anIndexes.length()) - EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()"); + EXCEPTION(runtime_error,"AddPrismsWithID - 7*aNbElems != anIndexes.length()"); for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1], anIndexes[anIndexId+2], @@ -247,6 +277,9 @@ namespace{ } + //======================================================================= + //function : AddHexasWithID + //======================================================================= inline void AddHexasWithID(SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) @@ -254,7 +287,7 @@ namespace{ const SMESH::long_array& anIndexes = theSeq[theId].indexes; CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; if(9*aNbElems != anIndexes.length()) - EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()"); + EXCEPTION(runtime_error,"AddHexasWithID - 9*aNbElems != anIndexes.length()"); for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){ SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1], anIndexes[anIndexId+2], @@ -271,6 +304,9 @@ namespace{ } + //======================================================================= + //function : AddPolyhedronsWithID + //======================================================================= inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) @@ -302,6 +338,217 @@ namespace{ } + //======================================================================= + //function : AddQuadEdgesWithID + //======================================================================= + inline void AddQuadEdgesWithID(SMDS_Mesh* theMesh, + SMESH::log_array_var& theSeq, + CORBA::Long theId) + { + const SMESH::long_array& anIndexes = theSeq[theId].indexes; + CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; + if(4*aNbElems != anIndexes.length()) + EXCEPTION(runtime_error,"AddQuadEdgeWithID - 4*aNbElems != aCoords.length()"); + for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){ + SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId+14], + anIndexes[anIndexId+15], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId+14], + anIndexes[anIndexId+15], + anIndexes[anIndexId+16], + anIndexes[anIndexId+17], + anIndexes[anIndexId+18], + anIndexes[anIndexId+19], + anIndexes[anIndexId+20], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<2 ) return VTK_POLYGON; else if ( theNbNodes == 3 ) return VTK_TRIANGLE; else if ( theNbNodes == 4 ) return VTK_QUAD; + else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE; + else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD; else return VTK_EMPTY_CELL; case SMDSAbs_Volume: @@ -364,6 +615,18 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, else if ( theNbNodes == 5 ) return VTK_PYRAMID; else if ( theNbNodes == 6 ) return VTK_WEDGE; else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON; + else if ( theNbNodes == 10 ) { + cout<<"QUADRATIC_TETRA"< (aConnect[nn]); + // cout<<"k="<X()<<","<Y()<<","<Z()<<")"< 0) { @@ -806,6 +1092,14 @@ void SMESH_MeshObj::Update( int theIsClear ) case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break; case SMESH::ADD_POLYHEDRON : AddPolyhedronsWithID( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADEDGE : AddQuadEdgesWithID ( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADTRIANGLE : AddQuadTriasWithID ( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADQUADRANGLE : AddQuadQuadsWithID ( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADTETRAHEDRON: AddQuadTetrasWithID ( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADPYRAMID : AddQuadPiramidsWithID( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADPENTAHEDRON: AddQuadPentasWithID ( myMesh, aSeq, anId ); break; + case SMESH::ADD_QUADHEXAHEDRON : AddQuadHexasWithID ( myMesh, aSeq, anId ); break; + case SMESH::REMOVE_NODE: for( ; anElemId < aNbElems; anElemId++ ) myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) ); diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 9126f04f3..f2df1fd89 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -193,10 +193,31 @@ bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) return false; } +bool SMDS_MeshElement::IsValidIndex(const int ind) const +{ + return ( ind>-1 && indnext(); + nbe++; + } + return static_cast (it->next()); + } + return N; +} + bool SMDS_MeshElement::IsQuadratic() const { return false; } + bool SMDS_MeshElement::IsMediumNode(class SMDS_MeshNode* node) const { return false; diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 010173c94..4ba69f7ab 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -68,6 +68,15 @@ public: virtual int NbFaces() const; int GetID() const; + /** + * Return true if index of node is valid (0...NbNodes()-1) + */ + virtual bool IsValidIndex(const int ind) const; + /** + * Return node by it index (if index is valid) + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + ///Return the type of the current element virtual SMDSAbs_ElementType GetType() const = 0; virtual bool IsPoly() const { return false; }; diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 381b262ee..0fa7d2f0f 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -185,6 +185,184 @@ static int Hexa_RE [6][5] = { // REVERSED -> EXTERNAL { 1, 2, 6, 5, 1 }}; static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 }; + +/* +// N3 +// + +// /|\ +// 7/ | \8 +// / |4 \ QUADRATIC +// N0 +---|---+ N1 TETRAHEDRON +// \ +9 / +// \ | / +// 6\ | /5 +// \|/ +// + +// N2 +*/ +static int QuadTetra_F [4][7] = { // FORWARD == EXTERNAL + { 0, 4, 1, 5, 2, 6, 0 }, // All faces have external normals + { 0, 7, 3, 8, 1, 4, 0 }, + { 1, 8, 3, 9, 2, 5, 1 }, + { 0, 6, 2, 9, 3, 7, 0 }}; +static int QuadTetra_R [4][7] = { // REVERSED + { 0, 4, 1, 5, 2, 6, 0 }, // All faces but a bottom have external normals + { 0, 4, 1, 8, 3, 7, 0 }, + { 1, 5, 2, 9, 3, 8, 1 }, + { 0, 7, 3, 9, 2, 6, 0 }}; +static int QuadTetra_RE [4][7] = { // REVERSED -> FORWARD (EXTERNAL) + { 0, 6, 2, 5, 1, 4, 0 }, // All faces have external normals + { 0, 4, 1, 8, 3, 7, 0 }, + { 1, 5, 2, 9, 3, 8, 1 }, + { 0, 7, 3, 9, 2, 6, 0 }}; +static int QuadTetra_nbN [] = { 6, 6, 6, 6 }; + +// +// QUADRATIC +// PYRAMID +// +// +4 +// +// +// 10+-----+11 +// | | 9 - middle point for (0,4) etc. +// | | +// 9+-----+12 +// +// 6 +// 1+----+----+2 +// | | +// | | +// 5+ +7 +// | | +// | | +// 0+----+----+3 +// 8 +static int QuadPyram_F [5][9] = { // FORWARD == EXTERNAL + { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces have external normals + { 0, 9, 4, 10,1, 5, 0, 4, 4 }, + { 1, 10,4, 11,2, 6, 1, 4, 4 }, + { 2, 11,4, 12,3, 7, 2, 4, 4 }, + { 3, 12,4, 9, 0, 8, 3, 4, 4 }}; +static int QuadPyram_R [5][9] = { // REVERSED + { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces but a bottom have external normals + { 0, 5, 1, 10,4, 9, 0, 4, 4 }, + { 1, 6, 2, 11,4, 10,1, 4, 4 }, + { 2, 7, 3, 12,4, 11,2, 4, 4 }, + { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; +static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL) + { 0, 8, 3, 7, 2, 6, 1, 5, 0 }, // All faces but a bottom have external normals + { 0, 5, 1, 10,4, 9, 0, 4, 4 }, + { 1, 6, 2, 11,4, 10,1, 4, 4 }, + { 2, 7, 3, 12,4, 11,2, 4, 4 }, + { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; +static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 }; + +/* +// + N4 +// /|\ +// 9/ | \10 +// / | \ +// / | \ +// N3 +----+----+ N5 +// | |11 | +// | | | +// | +13 | QUADRATIC +// | | | PENTAHEDRON +// | | | +// | | | +// | | | +// 12+ | +14 +// | | | +// | | | +// | + N1 | +// | / \ | +// | 6/ \7 | +// | / \ | +// |/ \| +// N0 +---------+ N2 +// 8 +*/ +static int QuadPenta_F [5][9] = { // FORWARD + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Top face has an internal normal, other - external + { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 1, 13,4, 10,5, 14,2, 7, 1 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }}; +static int QuadPenta_R [5][9] = { // REVERSED + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Bottom face has an internal normal, other - external + { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 1, 7, 2, 14,5, 10,4, 13,1 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }}; +static int QuadPenta_FE [5][9] = { // FORWARD -> EXTERNAL + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, + { 3,11, 5, 10,4, 9, 3, 3, 3 }, + { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 1, 13,4, 10,5, 14,2, 7, 1 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }}; +static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL + { 0, 8, 2, 7, 1, 6, 0, 0, 0 }, + { 3, 9, 4, 10,5, 11,3, 3, 3 }, + { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 1, 7, 2, 14,5, 10,4, 13,1 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }}; +static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 }; + +/* +// 13 +// N5+-----+-----+N6 +// /| /| +// 12+ | 14+ | +// / | / | +// N4+-----+-----+N7 | QUADRATIC +// | | 15 | | HEXAHEDRON +// | | | | +// | 17+ | +18 +// | | | | +// | | | | +// | | | | +// 16+ | +19 | +// | | | | +// | | 9 | | +// | N1+-----+-|---+N2 +// | / | / +// | +8 | +10 +// |/ |/ +// N0+-----+-----+N3 +// 11 +*/ +static int QuadHexa_F [6][9] = { // FORWARD + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15,4 }, // odd face(1,3,5) normal is internal, even(0,2,4) - external + { 1, 8, 0, 16,4, 12,5, 17,1 }, // same index nodes of opposite faces are linked + { 2, 10,3, 19,7, 14,6, 18,2 }, + { 0, 11,3, 19,7, 15,4, 16,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }}; +// static int Hexa_R [6][5] = { // REVERSED +// { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, +// { 4, 7, 6, 5, 4 }, // odd face(1,3,5) normal is external, even(0,2,4) - internal +// { 1, 5, 4, 0, 1 }, // same index nodes of opposite faces are linked +// { 2, 6, 7, 3, 2 }, +// { 0, 4, 7, 3, 0 }, +// { 1, 5, 6, 2, 1 }}; +static int QuadHexa_FE [6][9] = { // FORWARD -> EXTERNAL + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, + { 4, 15,7, 14,6, 13,5, 12,4 }, // all face normals are external, + { 0, 16,4, 12,5, 17,1, 8, 0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 3, 10,2, 18,6, 14,7, 19,3 }, + { 0, 11,3, 19,7, 15,4, 16,0 }, + { 1, 17,5, 13,6, 18,2, 9, 1 }}; +static int QuadHexa_RE [6][9] = { // REVERSED -> EXTERNAL + { 0, 11,3, 10,2, 9, 1, 8, 0 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15,4 }, // all face normals are external, + { 0, 8, 1, 17,5, 12,4, 16,0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 3, 19,7, 14,6, 18,2, 10,3 }, + { 0, 16,4, 15,7, 19,3, 11,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }}; +static int QuadHexa_nbN [] = { 8, 8, 8, 8, 8, 8 }; + + // ======================================================== // to perform some calculations without linkage to CASCADE // ======================================================== @@ -323,12 +501,17 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) MESSAGE("Warning: bad volumic element"); return false; } - } else { + } + else { switch ( myVolumeNbNodes ) { case 4: case 5: case 6: - case 8: { + case 8: + case 10: + case 13: + case 15: + case 20: { // define volume orientation XYZ botNormal; GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z ); @@ -387,6 +570,34 @@ void SMDS_VolumeTool::Inverse () SWAP_NODES( myVolumeNodes, 1, 3 ); SWAP_NODES( myVolumeNodes, 5, 7 ); break; + + case 10: + SWAP_NODES( myVolumeNodes, 1, 2 ); + SWAP_NODES( myVolumeNodes, 4, 6 ); + SWAP_NODES( myVolumeNodes, 8, 9 ); + break; + case 13: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 8 ); + SWAP_NODES( myVolumeNodes, 6, 7 ); + SWAP_NODES( myVolumeNodes, 10, 12 ); + break; + case 15: + SWAP_NODES( myVolumeNodes, 1, 2 ); + SWAP_NODES( myVolumeNodes, 4, 5 ); + SWAP_NODES( myVolumeNodes, 6, 8 ); + SWAP_NODES( myVolumeNodes, 9, 11 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + break; + case 20: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 7 ); + SWAP_NODES( myVolumeNodes, 8, 11 ); + SWAP_NODES( myVolumeNodes, 9, 10 ); + SWAP_NODES( myVolumeNodes, 12, 15 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + SWAP_NODES( myVolumeNodes, 17, 19 ); + break; default:; } } @@ -402,14 +613,25 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const return POLYHEDA; if ( myVolume ) { - static const VolumeType types[] = { - TETRA, // myVolumeNbNodes = 4 - PYRAM, // myVolumeNbNodes = 5 - PENTA, // myVolumeNbNodes = 6 - UNKNOWN, // myVolumeNbNodes = 7 - HEXA // myVolumeNbNodes = 8 - }; - return types[ myVolumeNbNodes - 4 ]; +// static const VolumeType types[] = { +// TETRA, // myVolumeNbNodes = 4 +// PYRAM, // myVolumeNbNodes = 5 +// PENTA, // myVolumeNbNodes = 6 +// UNKNOWN, // myVolumeNbNodes = 7 +// HEXA // myVolumeNbNodes = 8 +// }; +// return types[ myVolumeNbNodes - 4 ]; + switch(myVolumeNbNodes) { + case 4: return TETRA; break; + case 5: return PYRAM; break; + case 6: return PENTA; break; + case 8: return HEXA; break; + case 10: return QUAD_TETRA; break; + case 13: return QUAD_PYRAM; break; + case 15: return QUAD_PENTA; break; + case 20: return QUAD_HEXA; break; + default: break; + } } return UNKNOWN; @@ -491,7 +713,7 @@ double SMDS_VolumeTool::GetSize() const else { const static int ind[] = { - 0, 1, 3, 6, 11 }; + 0, 1, 3, 6, 11, 19, 32, 35, 40}; const static int vtab[][4] = { // tetrahedron { 0, 1, 2, 3 }, @@ -507,6 +729,47 @@ double SMDS_VolumeTool::GetSize() const { 4, 1, 6, 5 }, { 1, 3, 6, 2 }, { 4, 6, 3, 7 }, + { 1, 4, 6, 3 }, + + // quadratic tetrahedron + { 0, 4, 6, 7 }, + { 1, 5, 4, 8 }, + { 2, 6, 5, 9 }, + { 7, 8, 9, 3 }, + { 4, 6, 7, 9 }, + { 4, 5, 6, 9 }, + { 4, 7, 8, 9 }, + { 4, 5, 9, 8 }, + //{ 6, 7, 9, 4 }, + //{ 5, 6, 9, 4 }, + //{ 7, 8, 9, 4 }, + //{ 5, 9, 8, 4 }, + + // quadratic pyramid + { 0, 5, 8, 9 }, + { 1, 5,10, 6 }, + { 2, 6,11, 7 }, + { 3, 7,12, 8 }, + { 4, 9,11,10 }, + { 4, 9,12,11 }, + { 10, 5, 9, 8 }, + { 10, 8, 9,12 }, + { 10, 8,12, 7 }, + { 10, 7,12,11 }, + { 10, 7,11, 6 }, + { 10, 5, 8, 6 }, + { 10, 6, 8, 7 }, + + // quadratic pentahedron + { 0, 1, 2, 3 }, + { 1, 5, 3, 4 }, + { 1, 5, 2, 3 }, + + // quadratic hexahedron + { 1, 4, 3, 0 }, + { 4, 1, 6, 5 }, + { 1, 3, 6, 2 }, + { 4, 6, 3, 7 }, { 1, 4, 6, 3 } }; @@ -514,13 +777,15 @@ double SMDS_VolumeTool::GetSize() const int n1 = ind[type]; int n2 = ind[type+1]; - for (int i = n1; i < n2; i++) - { +//cout<<"n1="< nodes_ids, std::vector quantities); + // special methods for quadratic elements + void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, int n14, int n24, int n34); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45); + void AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48); + void MoveNode(int NewNodeID, double x, double y, double z); void RemoveNode(int NodeID); void RemoveElement(int ElementID); diff --git a/src/SMESHDS/SMESHDS_CommandType.hxx b/src/SMESHDS/SMESHDS_CommandType.hxx index f2c505b1f..2f7455a58 100644 --- a/src/SMESHDS/SMESHDS_CommandType.hxx +++ b/src/SMESHDS/SMESHDS_CommandType.hxx @@ -30,22 +30,30 @@ //#include enum SMESHDS_CommandType { - SMESHDS_AddNode, - SMESHDS_AddEdge, - SMESHDS_AddTriangle, - SMESHDS_AddQuadrangle, - SMESHDS_AddPolygon, - SMESHDS_AddTetrahedron, - SMESHDS_AddPyramid, - SMESHDS_AddPrism, - SMESHDS_AddHexahedron, - SMESHDS_AddPolyhedron, - SMESHDS_RemoveNode, - SMESHDS_RemoveElement, - SMESHDS_MoveNode, - SMESHDS_ChangeElementNodes, - SMESHDS_ChangePolyhedronNodes, - SMESHDS_Renumber + SMESHDS_AddNode, + SMESHDS_AddEdge, + SMESHDS_AddTriangle, + SMESHDS_AddQuadrangle, + SMESHDS_AddPolygon, + SMESHDS_AddTetrahedron, + SMESHDS_AddPyramid, + SMESHDS_AddPrism, + SMESHDS_AddHexahedron, + SMESHDS_AddPolyhedron, + SMESHDS_RemoveNode, + SMESHDS_RemoveElement, + SMESHDS_MoveNode, + SMESHDS_ChangeElementNodes, + SMESHDS_ChangePolyhedronNodes, + SMESHDS_Renumber, + // special types for quadratic elements + SMESHDS_AddQuadEdge, + SMESHDS_AddQuadTriangle, + SMESHDS_AddQuadQuadrangle, + SMESHDS_AddQuadTetrahedron, + SMESHDS_AddQuadPyramid, + SMESHDS_AddQuadPentahedron, + SMESHDS_AddQuadHexahedron }; diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 5f92232dd..87e845ee8 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1063,3 +1063,460 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, SMESHDS_Mesh::~SMESHDS_Mesh() { } + + + +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID); + if(anElem) myScript->AddEdge(ID,n1,n2,n12); + return anElem; +} + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12); + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n12->GetID()); + return anElem; +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + return AddEdgeWithID(n1->GetID(), + n2->GetID(), + n12->GetID(), + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), + n12->GetID(), n23->GetID(), n31->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n14->GetID(), n24->GetID(), n34->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23, + n31,n14,n24,n34,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order tetrahedron of 10 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n14->GetID(), n24->GetID(), n34->GetID(), ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41, + n15,n25,n35,n45); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5, + n12,n23,n34,n41, + n15,n25,n35,n45,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41, + n15,n25,n35,n45); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order pyramid of 13 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n4->GetID(), n5->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n45->GetID(), n56->GetID(), n64->GetID(), + n14->GetID(), n25->GetID(), n36->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6, + n12,n23,n31, + n45,n56,n64, + n14,n25,n36,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron with 15 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n4->GetID(), n5->GetID(), n6->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n45->GetID(), n56->GetID(), n64->GetID(), + n14->GetID(), n25->GetID(), n36->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(), + ID); +} + + diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index a5a54907b..ee39cb642 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -93,6 +93,16 @@ public: virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + // 2d order edge with 3 nodes: n12 - node between n1 and n2 + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12); + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -113,6 +123,44 @@ public: const SMDS_MeshNode * n3, const SMDS_MeshNode * n4); + // 2d order triangle of 6 nodes + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + // 2d order quadrangle + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -171,6 +219,153 @@ public: const SMDS_MeshNode * n7, const SMDS_MeshNode * n8); + // 2d order tetrahedron of 10 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34); + + // 2d order pyramid of 13 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45); + + // 2d order Pentahedron with 15 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36); + + // 2d order Hexahedrons with 20 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, const int ID); diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index 369ab4697..7268a2ba7 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -245,3 +245,98 @@ const list& SMESHDS_Script::GetCommands() { return myCommands; } + + +//******************************************************************** +//***** Methods for quadratic elements ****** +//******************************************************************** + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +void SMESHDS_Script::AddEdge(int NewEdgeID, int n1, int n2, int n12) +{ + getCommand(SMESHDS_AddQuadEdge)->AddEdge(NewEdgeID, n1, n2, n12); +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31) +{ + getCommand(SMESHDS_AddQuadTriangle)->AddFace(NewFaceID, n1, n2, n3, + n12, n23, n31); +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41) +{ + getCommand(SMESHDS_AddQuadQuadrangle)->AddFace(NewFaceID, n1, n2, n3, n4, + n12, n23, n34, n41); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, + int n14, int n24, int n34) +{ + getCommand(SMESHDS_AddQuadTetrahedron)->AddVolume(NewVolID, n1, n2, n3, n4, + n12, n23, n31, + n14, n24, n34); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45) +{ + getCommand(SMESHDS_AddQuadPyramid)->AddVolume(NewVolID, n1, n2, n3, n4, n5, + n12, n23, n34, n41, + n15, n25, n35, n45); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5,int n6, int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36) +{ + getCommand(SMESHDS_AddQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6, + n12, n23, n31, + n45, n56, n64, + n14, n25, n36); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48) +{ + getCommand(SMESHDS_AddQuadHexahedron)->AddVolume(NewVolID, n1, n2, n3, n4, + n5, n6, n7, n8, + n12, n23, n34, n41, + n56, n67, n78, n85, + n15, n26, n37, n48); +} + diff --git a/src/SMESHDS/SMESHDS_Script.hxx b/src/SMESHDS/SMESHDS_Script.hxx index 3874facfc..04718fdcd 100644 --- a/src/SMESHDS/SMESHDS_Script.hxx +++ b/src/SMESHDS/SMESHDS_Script.hxx @@ -56,6 +56,27 @@ class SMESHDS_Script std::vector nodes_ids, std::vector quantities); + // special methods for quadratic elements + void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, int n14, int n24, int n34); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45); + void AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48); void MoveNode(int NewNodeID, double x, double y, double z); void RemoveNode(int NodeID); void RemoveElement(int ElementID); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 9aa35ea1e..848b1d59f 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -128,6 +128,17 @@ CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) TPythonDump() << "isDone = " << this << ".AddEdge([ " << index1 << ", " << index2 <<" ])"; } + if (NbNodes == 3) { + CORBA::Long n1 = IDsOfNodes[0]; + CORBA::Long n2 = IDsOfNodes[1]; + CORBA::Long n12 = IDsOfNodes[2]; + GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1), + GetMeshDS()->FindNode(n2), + GetMeshDS()->FindNode(n12)); + // Update Python script + TPythonDump() << "isDone = " << this << ".AddEdge([ " + <AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); } - else + else if (NbNodes == 6) + { + GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5]); + } + else if (NbNodes == 8) { - GetMeshDS()->AddPolygonalFace(nodes); + GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7]); } // Update Python script @@ -189,6 +206,30 @@ CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) return true; }; +//============================================================================= +/*! + * AddPolygonalFace + */ +//============================================================================= +CORBA::Boolean SMESH_MeshEditor_i::AddPolygonalFace + (const SMESH::long_array & IDsOfNodes) +{ + int NbNodes = IDsOfNodes.length(); + std::vector nodes (NbNodes); + for (int i = 0; i < NbNodes; i++) + nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + + GetMeshDS()->AddPolygonalFace(nodes); + + // Update Python script + TPythonDump() <<"isDone = "<AddVolume(n[0],n[1],n[2],n[3],n[4]); break; case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break; case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break; + case 10:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5], + n[6],n[7],n[8],n[9]); break; + case 13:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6], + n[7],n[8],n[9],n[10],n[11],n[12]); break; + case 15:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8], + n[9],n[10],n[11],n[12],n[13],n[14]); break; + case 20:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], + n[8],n[9],n[10],n[11],n[12],n[13],n[14], + n[15],n[16],n[17],n[18],n[19]); break; } // Update Python script TPythonDump() << "isDone = " << this << ".AddVolume( " << IDsOfNodes << " )"; diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index aa28198c1..0632747a6 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -50,6 +50,7 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z); CORBA::Boolean AddEdge(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddFace(const SMESH::long_array & IDsOfNodes); + CORBA::Boolean AddPolygonalFace(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddVolume(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes, diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index e40390c6e..9ffa37d1f 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -51,10 +51,21 @@ using namespace std; #include #include #include +#include +#include #include "utilities.h" #include "Utils_ExceptHandlers.hxx" +#ifndef StdMeshers_Array2OfNode_HeaderFile +#define StdMeshers_Array2OfNode_HeaderFile +typedef const SMDS_MeshNode* SMDS_MeshNodePtr; +#include +DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr) +DEFINE_ARRAY2(StdMeshers_Array2OfNode, + StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr) +#endif + //============================================================================= /*! @@ -117,7 +128,28 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); aMesh.GetSubMesh(aShape); - FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape); + //FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape); + FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape); + + if (!quad) + return false; + + if(myQuadranglePreference) { + int n1 = quad->nbPts[0]; + int n2 = quad->nbPts[1]; + int n3 = quad->nbPts[2]; + int n4 = quad->nbPts[3]; + int nfull = n1+n2+n3+n4; + int ntmp = nfull/2; + ntmp = ntmp*2; + if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) { + // special path for using only quandrangle faces + return ComputeQuadPref(aMesh, aShape, quad); + } + } + + // set normalized grid on unit square in parametric domain + SetNormalizedGrid(aMesh, aShape, quad); if (!quad) return false; @@ -490,14 +522,16 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, return isOk; } + //============================================================================= /*! * */ //============================================================================= -FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute - (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception) +FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) + throw(SALOME_Exception) { Unexpect aCatch(SalomeException); @@ -505,42 +539,56 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute // verify 1 wire only, with 4 edges - if (NumberOfWires(F) != 1) - { + if (NumberOfWires(F) != 1) { INFOS("only 1 wire by face (quadrangles)"); return 0; } const TopoDS_Wire& W = BRepTools::OuterWire(F); BRepTools_WireExplorer wexp (W, F); - FaceQuadStruct *quad = new FaceQuadStruct; + FaceQuadStruct* quad = new FaceQuadStruct; for (int i = 0; i < 4; i++) quad->uv_edges[i] = 0; quad->uv_grid = 0; int nbEdges = 0; - for (wexp.Init(W, F); wexp.More(); wexp.Next()) - { + for (wexp.Init(W, F); wexp.More(); wexp.Next()) { const TopoDS_Edge& E = wexp.Current(); int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - if (nbEdges < 4) - { + if (nbEdges < 4) { quad->edge[nbEdges] = E; quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema } nbEdges++; } - if (nbEdges != 4) - { + if (nbEdges != 4) { INFOS("face must have 4 edges /quadrangles"); QuadDelete(quad); return 0; } - // set normalized grid on unit square in parametric domain + return quad; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute + (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + + FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); + + if(!quad) return 0; - SetNormalizedGrid(aMesh, F, quad); + // set normalized grid on unit square in parametric domain + SetNormalizedGrid(aMesh, aShape, quad); return quad; } @@ -789,6 +837,654 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, } } + +//======================================================================= +//function : ShiftQuad +//purpose : auxilary function for ComputeQuadPref +//======================================================================= +static void ShiftQuad(FaceQuadStruct* quad, const int num, bool WisF) +{ + if(num>3) return; + int i; + for(i=1; i<=num; i++) { + int nbPts3 = quad->nbPts[0]; + quad->nbPts[0] = quad->nbPts[1]; + quad->nbPts[1] = quad->nbPts[2]; + quad->nbPts[2] = quad->nbPts[3]; + quad->nbPts[3] = nbPts3; + TopoDS_Edge edge3 = quad->edge[0]; + quad->edge[0] = quad->edge[1]; + quad->edge[1] = quad->edge[2]; + quad->edge[2] = quad->edge[3]; + quad->edge[3] = edge3; + double first3 = quad->first[0]; + quad->first[0] = quad->first[1]; + quad->first[1] = quad->first[2]; + quad->first[2] = quad->first[3]; + quad->first[3] = first3; + double last3 = quad->last[0]; + quad->last[0] = quad->last[1]; + quad->last[1] = quad->last[2]; + quad->last[2] = quad->last[3]; + quad->last[3] = last3; + bool isEdgeForward3 = quad->isEdgeForward[0]; + quad->isEdgeForward[0] = quad->isEdgeForward[1]; + quad->isEdgeForward[1] = quad->isEdgeForward[2]; + quad->isEdgeForward[2] = quad->isEdgeForward[3]; + quad->isEdgeForward[3] = isEdgeForward3; + bool isEdgeOut3 = quad->isEdgeOut[0]; + quad->isEdgeOut[0] = quad->isEdgeOut[1]; + quad->isEdgeOut[1] = quad->isEdgeOut[2]; + quad->isEdgeOut[2] = quad->isEdgeOut[3]; + quad->isEdgeOut[3] = isEdgeOut3; + UVPtStruct* uv_edges3 = quad->uv_edges[0]; + quad->uv_edges[0] = quad->uv_edges[1]; + quad->uv_edges[1] = quad->uv_edges[2]; + quad->uv_edges[2] = quad->uv_edges[3]; + quad->uv_edges[3] = uv_edges3; + } + if(!WisF) { + // replacement left and right edges + int nbPts3 = quad->nbPts[1]; + quad->nbPts[1] = quad->nbPts[3]; + quad->nbPts[3] = nbPts3; + TopoDS_Edge edge3 = quad->edge[1]; + quad->edge[1] = quad->edge[3]; + quad->edge[3] = edge3; + double first3 = quad->first[1]; + quad->first[1] = quad->first[3]; + quad->first[3] = first3; + double last3 = quad->last[1]; + quad->last[1] = quad->last[2]; + quad->last[3] = last3; + bool isEdgeForward3 = quad->isEdgeForward[1]; + quad->isEdgeForward[1] = quad->isEdgeForward[3]; + quad->isEdgeForward[3] = isEdgeForward3; + bool isEdgeOut3 = quad->isEdgeOut[1]; + quad->isEdgeOut[1] = quad->isEdgeOut[3]; + quad->isEdgeOut[3] = isEdgeOut3; + UVPtStruct* uv_edges3 = quad->uv_edges[1]; + quad->uv_edges[1] = quad->uv_edges[3]; + quad->uv_edges[3] = uv_edges3; + } +} + + +//======================================================================= +//function : CalcUV +//purpose : auxilary function for ComputeQuadPref +//======================================================================= +static gp_XY CalcUV(double x0, double x1, double y0, double y1, + FaceQuadStruct* quad, + const gp_Pnt2d& a0, const gp_Pnt2d& a1, + const gp_Pnt2d& a2, const gp_Pnt2d& a3, + const Handle(Geom2d_Curve)& c2db, + const Handle(Geom2d_Curve)& c2dr, + const Handle(Geom2d_Curve)& c2dt, + const Handle(Geom2d_Curve)& c2dl) +{ + int nb = quad->nbPts[0]; + int nr = quad->nbPts[1]; + int nt = quad->nbPts[2]; + int nl = quad->nbPts[3]; + + UVPtStruct* uv_eb = quad->uv_edges[0]; + UVPtStruct* uv_er = quad->uv_edges[1]; + UVPtStruct* uv_et = quad->uv_edges[2]; + UVPtStruct* uv_el = quad->uv_edges[3]; + + double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); + double y = y0 + x * (y1 - y0); + + double param_b = uv_eb[0].param + x * (uv_eb[nb-1].param - uv_eb[0].param); + double param_t = uv_et[0].param + x * (uv_et[nt-1].param - uv_et[0].param); + double param_r = uv_er[0].param + y * (uv_er[nr-1].param - uv_er[0].param); + double param_l = uv_el[0].param + y * (uv_el[nl-1].param - uv_el[0].param); + + gp_Pnt2d p0 = c2db->Value(param_b); + gp_Pnt2d p1 = c2dr->Value(param_r); + gp_Pnt2d p2 = c2dt->Value(param_t); + gp_Pnt2d p3 = c2dl->Value(param_l); + + double u = (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X(); + double v = (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y(); + + u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() + + x * y * a2.X() + (1 - x) * y * a3.X(); + v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() + + x * y * a2.Y() + (1 - x) * y * a3.Y(); + + //cout<<"x0="<ShapeToIndex( F ); + + int nb = quad->nbPts[0]; + int nr = quad->nbPts[1]; + int nt = quad->nbPts[2]; + int nl = quad->nbPts[3]; + int dh = abs(nb-nt); + int dv = abs(nr-nl); + + if( dh>=dv ) { + if( nt>nb ) { + // it is a base case => not shift quad but me be replacement is need + ShiftQuad(quad,0,WisF); + } + else { + // we have to shift quad on 2 + ShiftQuad(quad,2,WisF); + } + } + else { + if( nr>nl ) { + // we have to shift quad on 3 + ShiftQuad(quad,3,WisF); + } + else { + // we have to shift quad on 1 + ShiftQuad(quad,1,WisF); + } + } + + nb = quad->nbPts[0]; + nr = quad->nbPts[1]; + nt = quad->nbPts[2]; + nl = quad->nbPts[3]; + dh = abs(nb-nt); + dv = abs(nr-nl); + int nbh = Max(nb,nt); + int nbv = Max(nr,nl); + int addh = 0; + int addv = 0; + + // orientation of face and 3 main domain for future faces + // 0 top 1 + // 1------------1 + // | | | | + // | | | | + // | L | | R | + // left | | | | rigth + // | / \ | + // | / C \ | + // |/ \| + // 0------------0 + // 0 bottom 1 + + if(dh>dv) { + addv = (dh-dv)/2; + nbv = nbv + addv; + } + else { // dv>=dh + addh = (dv-dh)/2; + nbh = nbh + addh; + } + + Handle(Geom2d_Curve) c2d[4]; + for(i=0; i<4; i++) { + c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i], F, + quad->first[i], quad->last[i]); + } + + bool loadOk = true; + for(i=0; i<2; i++) { + quad->uv_edges[i] = LoadEdgePoints2(aMesh, F, quad->edge[i], false); + if(!quad->uv_edges[i]) loadOk = false; + } + for(i=2; i<4; i++) { + quad->uv_edges[i] = LoadEdgePoints2(aMesh, F, quad->edge[i], true); + if (!quad->uv_edges[i]) loadOk = false; + } + if (!loadOk) { + INFOS("StdMeshers_Quadrangle_2D::ComputeQuadPref - LoadEdgePoints failed"); + QuadDelete( quad ); + quad = 0; + return false; + } + + UVPtStruct* uv_eb = quad->uv_edges[0]; + UVPtStruct* uv_er = quad->uv_edges[1]; + UVPtStruct* uv_et = quad->uv_edges[2]; + UVPtStruct* uv_el = quad->uv_edges[3]; + + // arrays for normalized params + //cout<<"Dump B:"<X()<<","<Y()<<","<Z()<<")"<D0(uv_eb[0].param,a[0]); + c2d[0]->D0(uv_eb[nb-1].param,a[1]); + c2d[2]->D0(uv_et[nt-1].param,a[2]); + c2d[2]->D0(uv_et[0].param,a[3]); + //cout<<" a[0]("<0) { + // add top nodes + for(i=1; i<=dl; i++) + NodesL.SetValue(i+1,nl,uv_et[i].node); + // create and add needed nodes + TColgp_SequenceOfXY UVtmp; + for(i=1; i<=dl; i++) { + double x0 = npt.Value(i+1); + double x1 = x0; + // diagonal node + double y0 = npl.Value(i+1); + double y1 = npr.Value(i+1); + gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3], + c2d[0], c2d[1], c2d[2], c2d[3]); + gp_Pnt P = S->Value(UV.X(),UV.Y()); + SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesL.SetValue(i+1,1,N); + if(UVL.Length()Value(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesL.SetValue(i+1,j,N); + if( i==dl ) UVtmp.Append(UV); + } + } + for(i=1; i<=UVtmp.Length() && UVL.Length()X()<<","<Y()<<","<Z()<<")"; + // } + // cout<AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); + meshDS->SetMeshElementOnShape(F, geomFaceID); + } + else { + SMDS_MeshFace* F = + meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), + NodesL.Value(i+1,j+1), NodesL.Value(i+1,j)); + meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + } + else { + // fill UVL using c2d + for(i=1; iD0(uv_el[i].param,p2d); + UVL.Append(p2d.XY()); + } + } + + // step2: create faces for right domain + StdMeshers_Array2OfNode NodesR(1,dr+1,1,nr); + // add right nodes + for(j=1; j<=nr; j++) + NodesR.SetValue(1,j,uv_er[nr-j].node); + if(dr>0) { + // add top nodes + for(i=1; i<=dr; i++) + NodesR.SetValue(i+1,1,uv_et[nt-1-i].node); + // create and add needed nodes + TColgp_SequenceOfXY UVtmp; + for(i=1; i<=dr; i++) { + double x0 = npt.Value(nt-i); + double x1 = x0; + // diagonal node + double y0 = npl.Value(i+1); + double y1 = npr.Value(i+1); + gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3], + c2d[0], c2d[1], c2d[2], c2d[3]); + gp_Pnt P = S->Value(UV.X(),UV.Y()); + SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesR.SetValue(i+1,nr,N); + if(UVR.Length()Value(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesR.SetValue(i+1,j,N); + if( i==dr ) UVtmp.Prepend(UV); + } + } + for(i=1; i<=UVtmp.Length() && UVR.Length()AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); + meshDS->SetMeshElementOnShape(F, geomFaceID); + } + else { + SMDS_MeshFace* F = + meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), + NodesR.Value(i+1,j+1), NodesR.Value(i+1,j)); + meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + } + else { + // fill UVR using c2d + for(i=1; iD0(uv_er[i].param,p2d); + UVR.Append(p2d.XY()); + } + } + + // step3: create faces for central domain + StdMeshers_Array2OfNode NodesC(1,nb,1,nbv); + // add first string using NodesL + for(i=1; i<=dl+1; i++) + NodesC.SetValue(1,i,NodesL(i,1)); + for(i=2; i<=nl; i++) + NodesC.SetValue(1,dl+i,NodesL(dl+1,i)); + // add last string using NodesR + for(i=1; i<=dr+1; i++) + NodesC.SetValue(nb,i,NodesR(i,nr)); + for(i=1; iD0(uv_eb[i-1].param,p2d); + } + // create and add needed nodes + // add linear layers + for(i=2; iValue(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesC.SetValue(i,nbv-nnn+j,N); + } + } + // add diagonal layers + //cout<<"UVL.Length()="<Value(u,v); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, u, v); + NodesC.SetValue(j,i+1,N); + } + } + // create faces + for(i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); + meshDS->SetMeshElementOnShape(F, geomFaceID); + } + else { + SMDS_MeshFace* F = + meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), + NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); + meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + + QuadDelete(quad); + bool isOk = true; + return isOk; +} + + +//============================================================================= +/*! + * LoadEdgePoints2 + */ +//============================================================================= +UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints2 (SMESH_Mesh & aMesh, + const TopoDS_Face& F, + const TopoDS_Edge& E, + bool IsReverse) +{ + //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints"); + // --- IDNodes of first and last Vertex + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + + ASSERT(!VFirst.IsNull()); + SMDS_NodeIteratorPtr lid = aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes(); + if (!lid->more()) { + MESSAGE ( "NO NODE BUILT ON VERTEX" ); + return 0; + } + const SMDS_MeshNode* idFirst = lid->next(); + + ASSERT(!VLast.IsNull()); + lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); + if (!lid->more()) { + MESSAGE ( "NO NODE BUILT ON VERTEX" ); + return 0; + } + const SMDS_MeshNode* idLast = lid->next(); + + // --- edge internal IDNodes (relies on good order storage, not checked) + + map params; + SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + if (nbPoints != params.size()) { + MESSAGE( "BAD NODE ON EDGE POSITIONS" ); + return 0; + } + UVPtStruct* uvslf = new UVPtStruct[nbPoints + 2]; + + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + + const TopoDS_Wire& W = BRepTools::OuterWire(F); + bool FisF = (F.Orientation()==TopAbs_FORWARD); + bool WisF = (W.Orientation()==TopAbs_FORWARD); + bool isForward = (E.Orientation()==TopAbs_FORWARD); + //if(isForward) cout<<"E is FORWARD"<Value(f); // first point = Vertex Forward + uvslf[0].x = p.X(); + uvslf[0].y = p.Y(); + uvslf[0].param = f; + uvslf[0].node = idFirst; + //MESSAGE("__ f "<::iterator itp = params.begin(); + for (int i = 1; i <= nbPoints; i++) { // nbPoints internal + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param); + uvslf[i].x = p.X(); + uvslf[i].y = p.Y(); + uvslf[i].param = param; + uvslf[i].node = (*itp).second; + //MESSAGE("__ "<Value(l); // last point = Vertex Reversed + uvslf[nbPoints + 1].x = p.X(); + uvslf[nbPoints + 1].y = p.Y(); + uvslf[nbPoints + 1].param = l; + uvslf[nbPoints + 1].node = idLast; + //MESSAGE("__ l "<Value(l); // first point = Vertex Reversed + uvslf[0].x = p.X(); + uvslf[0].y = p.Y(); + uvslf[0].param = l; + uvslf[0].node = idLast; + //MESSAGE("__ l "<::reverse_iterator itp = params.rbegin(); + for (int j = nbPoints; j >= 1; j--) { // nbPoints internal + double param = (*itp).first; + int i = nbPoints + 1 - j; + gp_Pnt2d p = C2d->Value(param); + uvslf[i].x = p.X(); + uvslf[i].y = p.Y(); + uvslf[i].param = param; + uvslf[i].node = (*itp).second; + //MESSAGE("__ "<Value(f); // last point = Vertex Forward + uvslf[nbPoints + 1].x = p.X(); + uvslf[nbPoints + 1].y = p.Y(); + uvslf[nbPoints + 1].param = f; + uvslf[nbPoints + 1].node = idFirst; + //MESSAGE("__ f "<