void no_DestroyNode(CEditRegion *pRegion, CWorldNode *pNode, BOOL bDeleteChildren) { GPOS pos; NODEOPS_CHECK(pRegion->CheckNodes() == NULL); #ifdef DIRECTEDITOR_BUILD GetNodeView()->RemoveFromTree(pNode); pNode->RemoveFromTree(); GetNodeView()->DeleteNode(pNode); #endif if(pNode->IsFlagSet(NODEFLAG_SELECTED)) pRegion->UnselectNode(pNode); pRegion->RemoveNodeFromPath(pNode); // Either delete or reattach the children. if(bDeleteChildren) { for(pos=pNode->m_Children; pos; ) { no_DestroyNode(pRegion, pNode->m_Children.GetNext(pos), TRUE); } } else { // Just attach the children to the parent node. for(pos=pNode->m_Children; pos; ) { no_AttachNode(pRegion, pNode->m_Children.GetNext(pos), pNode->GetParent()); } } NODEOPS_CHECK(pNode->m_Children.GetSize() == 0); // Detach from its parent. no_DetachNode(pRegion, pNode, FALSE); NODEOPS_CHECK(pRegion->CheckNodes() == NULL); // Remove it from a CEditRegion list if it's in one. if(pNode->GetType() == Node_Brush) { pRegion->RemoveBrush(pNode->AsBrush()); } else if(pNode->GetType() == Node_Object) { pRegion->RemoveObject(pNode->AsObject()); } NODEOPS_CHECK(pRegion->CheckNodes() == NULL); delete pNode; NODEOPS_CHECK(pRegion->CheckNodes() == NULL); }
// Attaches the node to the parent. void no_AttachNode(CEditRegion *pRegion, CWorldNode *pChild, CWorldNode *pParent) { if(!pParent) pParent = &pRegion->m_RootNode; no_DetachNode(pRegion, pChild, FALSE); pChild->SetParent(pParent); NODEOPS_CHECK(pParent->m_Children.FindElement(pChild) == BAD_INDEX); // Really slows down LandExport in debug so LandExport turns this option off. if(g_bCheckNodes) { NODEOPS_CHECK(pRegion->CheckNodes(pParent) == NULL); } pParent->m_Children.Append(pChild); if(g_bCheckNodes) { NODEOPS_CHECK(pRegion->CheckNodes(pParent) == NULL); } #ifdef DIRECTEDITOR_BUILD // Set the node in the node view if we are working on the active region if (pRegion == GetActiveRegionDoc()->GetRegion()) { GetNodeView( )->SetNode(pChild); } #endif }
//----------------------------------------------------------------------------------- // // CEditClipboard::CopyParenthood( ) // // Purpose: Copy parenthood associations from src to dest. This is done // by looping over the source nodes and looking for the one's with a // parent node. If the parent node is also in src, then the indices // linking child to parent for src are identical for dest. This // function only works if the number of elements in src and dest are // equal. // //----------------------------------------------------------------------------------- void CEditClipboard::CopyParenthood( CMoArray< CWorldNode * > &src, CMoArray< CWorldNode * > &dest ) { DWORD dwChildIndex, dwParentIndex; CWorldNode *pSrcChildNode, *pSrcParentNode, *pDestChildNode, *pDestParentNode; // This only works if src and dest have same number of elements... if( src.GetSize( ) != dest.GetSize( )) return; // Loop through all src nodes... for( dwChildIndex = 0; dwChildIndex < src.GetSize( ); dwChildIndex++ ) { // Get pointers to nodes and make sure a parent exists... pSrcChildNode = src[ dwChildIndex ]; pSrcParentNode = pSrcChildNode->GetParent( ); if( pSrcParentNode == NULL ) continue; // Loop through all the src nodes again, skipping the current one... for( dwParentIndex = 0; dwParentIndex < src.GetSize( ); dwParentIndex++ ) { if( dwParentIndex == dwChildIndex ) continue; // The parent node is in src, so quit out of this loop... if( pSrcParentNode == src[ dwParentIndex ]) break; } // If we found a parent in src, then use indices from src to set // parent in dest... if( dwParentIndex < src.GetSize( )) { pDestChildNode = dest[ dwChildIndex ]; pDestParentNode = dest[ dwParentIndex ]; if( pDestChildNode->GetParent( )) pDestChildNode->GetParent( )->RemoveChild( pDestChildNode ); pDestChildNode->SetParent( pDestParentNode ); // Update the tree item if it exists... if( pDestChildNode->GetItem( )) GetNodeView( )->SetNode( pDestChildNode ); pDestParentNode->m_Children.Append( pDestChildNode ); } } }
void no_DetachNode(CEditRegion *pRegion, CWorldNode *pNode, BOOL bAttachToRoot) { if(pNode->GetParent()) { pNode->GetParent()->m_Children.RemoveAt(pNode); } if(bAttachToRoot) { pNode->SetParent(&pRegion->m_RootNode); #ifdef DIRECTEDITOR_BUILD GetNodeView()->SetNode(pNode); #endif pRegion->m_RootNode.m_Children.Append(pNode); } else { pNode->SetParent(NULL); } }
void ReplaceNode_Execute(CUndoMgr *pMgr, CEditAction *pInputAction) { CWorldNode *pNode, *pOldNode, *pParent, *pChild; CNodeReplacement *pAction; DWORD i; CEditRegion *pRegion; pRegion = &pMgr->m_pDoc->m_Region; pAction = (CNodeReplacement*)pInputAction; pNode = pAction->m_pNode; ASSERT(pRegion->CheckNodes() == NULL); // Get rid of the node currently there. pOldNode = pRegion->FindNodeByID(pAction->m_NodeID); if(pOldNode) { no_DestroyNode(pRegion, pOldNode, FALSE); } ASSERT(pRegion->CheckNodes() == NULL); if(pNode) { // Initialize the replacement node. no_InitializeNewNode(pRegion, pNode, NULL); ASSERT(pRegion->CheckNodes() == NULL); // Parent/child relationship. pParent = pRegion->FindNodeByID(pAction->m_ParentID); //ASSERT(pParent); no_AttachNode(pRegion, pAction->m_pNode, pParent); ASSERT(pRegion->CheckNodes() == NULL); for(i=0; i < pAction->m_ChildrenIDs; i++) { pChild = pRegion->FindNodeByID(pAction->m_ChildrenIDs[i]); //ASSERT(pChild); if (pChild) { no_AttachNode(pRegion, pChild, pNode); } } // If we have children involved, we need to make sure they have proper tree items -DC if (pAction->m_ChildrenIDs > 0) { GetNodeView()->AddItemsToTree(pNode); } ASSERT(pRegion->CheckNodes() == NULL); // Special stuff if we're a brush. if(pNode->GetType() == Node_Brush) { for(i=0; i < pNode->AsBrush()->m_Polies; i++) { for(uint32 nCurrTex = 0; nCurrTex < CEditPoly::NUM_TEXTURES; nCurrTex++) { pNode->AsBrush()->m_Polies[i]->GetTexture(nCurrTex).UpdateTextureID(); } } } ASSERT(pRegion->CheckNodes() == NULL); // Clear the action's node since we moved it into the world. pAction->m_pNode = NULL; } ASSERT(pRegion->CheckNodes() == NULL); }
InterfaceT)::ProjectNodes_SlavetoMaster_Orthogonal() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all nodes of the slave side and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; #if 0 std::cout << "now projecting\n " << *snode; #endif if (NodePID(snode->Id()) != lcomm_->getRank()) continue; const double* sx = snode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode = Teuchos::null; // find a node on the master side, that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; const double* mx = mnode->XCoords(); // build distance | mnode->XCoords() - snode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist <= mindist) { mindist = dist; closenode = mnode; } // std::cout << "snode " << snode->Id() << " mnode " << mnode->Id() << " // mindist " << mindist << " dist " << dist << std::endl; } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Weired: for slave node " << snode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } // get segments attached to closest node cnode int nmseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** msegs = closenode->Segments(); // create a projection-iterator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // loop segments and find all projections onto them int nsseg = snode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** ssegs = snode->Segments(); for (int i = 0; i < nmseg; ++i) { // loop all segments that are adjacent to the slave node for (int j = 0; j < nsseg; ++j) { // project the slave node onto that master segment double xi[2]; xi[0] = xi[1] = 0.0; double gap; projector.ProjectNodetoSegment_Orthogonal_to_Slave( *snode, *(msegs[i]), xi, gap, *(ssegs[j])); // check whether this projection is good bool ok = false; if (IsOneDimensional()) { if (abs(xi[0]) < 1.01) ok = true; } else { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** not impl. for 3D\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (ok) // the projection is good { // create a projected node and store it in snode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, xi, msegs[i], ssegs[j]->Id()); snode->SetProjectedNode(pnode); snode->SetGap(gap); #if 0 std::cout << " snode id: " << pnode->Id() << " projects on mseg: " << msegs[i]->Id() << " orth to sseg " << ssegs[j]->Id() << std::endl; #endif } } // for (int j=0; j<nsseg; ++j) } // for (int i=0; i<nmseg; ++i) } // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr) // loop all slave nodes again and make projections redundant if (lcomm_->getSize() > 1) { std::vector<double> bcast(10 * rnode_[sside].size()); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; if (proc != NodePID(snode->Id())) continue; // cannot have a projection on a node i don't own int npnode = 0; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)>* pnode = snode->GetProjectedNode(npnode); if (!pnode) continue; // no projection on this one bcast[blength] = (double)snode->Id(); ++blength; bcast[blength] = (double)npnode; ++blength; for (int j = 0; j < npnode; ++j) { bcast[blength] = (double)pnode[j]->Segment()->Id(); ++blength; const double* xi = pnode[j]->Xi(); bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = pnode[j]->OrthoSegment(); ++blength; bcast[blength] = pnode[j]->Gap(); ++blength; } if ((int)bcast.size() < blength + 20) bcast.resize(bcast.size() + 40); } // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); // ++mcurr) if (blength >= (int)bcast.size()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc==lComm()->MyPID()) Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); if (proc != lcomm_->getRank()) bcast.resize(blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = GetNodeView(nid); int npnode = (int)bcast[i]; ++i; for (int j = 0; j < npnode; ++j) { int sid = (int)bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; int orthseg = (int)bcast[i]; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = GetSegmentView(sid); MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, xi, seg.get(), orthseg); snode->SetProjectedNode(pnode); snode->SetGap(gap); } } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Mismatch in dimension of recv buffer: " << i << " != " << blength << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc!=lComm()->MyPID()) } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); } // if (lComm()->NumProc()>1) #if 1 // Postprocess the projections // The slave side of the interface might be larger then the master side // of the interface so not all slave nodes have a projection. // For those slave nodes without a projection attached to a slave segment // which overlaps with the master side, Lagrange multipliers have to be // introduced. This is done by checking all nodes without a projection // whether they are attached to some slave segment on which another node // HAS a projection. If this case is found, a pseudo ProjectedNode is // introduced for that node. for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; // do only my own nodes // don't do anything on nodes that already have a projection if (snode->GetProjectedNode() != Teuchos::null) continue; // get segments adjacent to this node int nseg = snode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = snode->Segments(); // loop segments and check for other nodes with projection bool foundit = false; for (int i = 0; i < nseg; ++i) { int nnode = segs[i]->Nnode(); MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** nodes = segs[i]->Nodes(); for (int j = 0; j < nnode; ++j) if (nodes[j]->GetProjectedNode() != Teuchos::null) if (nodes[j]->GetProjectedNode()->Segment()) { foundit = true; break; } if (foundit) break; } if (foundit) { #if 0 std::cout << "Node without projection:\n" << *snode; std::cout << "...get's lagrange multipliers\n\n"; #endif MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, NULL, NULL); snode->SetProjectedNode(pnode); snode->SetGap(0.); } } #endif return true; }
InterfaceT)::ProjectNodes_MastertoSlave_Orthogonal() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all master nodes and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (NodePID(mnode->Id()) != lcomm_->getRank()) continue; const double* mx = mnode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode = Teuchos::null; // find a node on the slave side that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; const double* sx = snode->XCoords(); // build distance | snode->XCoords() - mnode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist < mindist) { mindist = dist; closenode = snode; } } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Weired: for master node " << mnode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } // get segments attached to closest node closenode int nseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments(); // create a projection operator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // loop these segments and find best projection double bestdist[2]; double bestgap = 0.0, gap; bestdist[0] = bestdist[1] = 1.0e+20; MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL; for (int i = 0; i < nseg; ++i) { // project the master node orthogonally on the slave segment double xi[2]; xi[0] = xi[1] = 0.0; projector.ProjectNodetoSegment_SegmentOrthogonal( *mnode, *(segs[i]), xi, gap); // check whether xi is better than previous projection if (IsOneDimensional()) { if (abs(xi[0]) < abs(bestdist[0])) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } else { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** not impl. for 3D\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // for (int i=0; i<nseg; ++i) // check whether this best projection is good bool ok = false; if (IsOneDimensional()) { if (abs(bestdist[0]) < 1.01) ok = true; } else { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** not impl. for 3D\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (ok) // the projection is good { // create a projected node and store it in mnode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, bestdist, bestseg); mnode->SetProjectedNode(pnode); mnode->SetGap(bestgap); } else // this mnode does not have a valid projection { if (OutLevel() > 6) std::cout << "MoertelT: ***WRN***: Node " << mnode->Id() << " does not have projection\n\n"; // mnode->SetProjectedNode(NULL); } } // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); ++mcurr) // loop all master nodes again and make projection redundant int bsize = 4 * rnode_[mside].size(); std::vector<double> bcast(bsize); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (proc != NodePID(mnode->Id())) continue; // cannot have a projection on a node i don't own Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode = mnode->GetProjectedNode(); if (pnode == Teuchos::null) continue; // this node does not have a projection const double* xi = pnode->Xi(); bcast[blength] = (double)pnode->Id(); ++blength; bcast[blength] = (double)pnode->Segment()->Id(); ++blength; bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = pnode->Gap(); ++blength; } // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); // ++mcurr) if (blength > bsize) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc==lComm()->MyPID()) Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; int sid = (int)bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = GetNodeView(nid); Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = GetSegmentView(sid); if (mnode == Teuchos::null || seg == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Cannot get view of node or segment\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, xi, seg.get()); mnode->SetProjectedNode(pnode); mnode->SetGap(gap); } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Mismatch in dimension of recv buffer: " << i << " != " << blength << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc!=lComm()->MyPID()) } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); return true; }
InterfaceT)::ProjectNodes_MastertoSlave_NormalField() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all nodes of the master side and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (NodePID(mnode->Id()) != lcomm_->getRank()) continue; const double* mx = mnode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::(NodeT)> closenode = Teuchos::null; // find a node on the slave side that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; const double* sx = snode->XCoords(); // build distance | snode->XCoords() - mnode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist < mindist) { mindist = dist; closenode = snode; } } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Weired: for master node " << mnode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } #if 0 std::cout << "snode " << *mnode; std::cout << "closenode " << *closenode; #endif // get segments attached to closest node closenode int nseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments(); // create a projection operator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // loop these segments and find best projection double bestdist[2]; const double tol = 0.2; double bestgap = 0.0, gap; bestdist[0] = bestdist[1] = 1.0e+20; MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL; for (int i = 0; i < nseg; ++i) { // project the master node on the slave segment along the segments // interpolated normal field double xi[2]; xi[0] = xi[1] = 0.0; projector.ProjectNodetoSegment_SegmentNormal(*mnode, *(segs[i]), xi, gap); // check whether xi is better then previous projections if (IsOneDimensional()) { if (abs(xi[0]) < abs(bestdist[0])) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } else { double third = 1. / 3.; // it's 'inside' with some tolerance if (xi[0] <= 1. + tol && xi[1] <= abs(1. - xi[0]) + tol && xi[0] >= 0. - tol && xi[1] >= 0. - tol) { // it's better in both directions if (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third))) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } // it's better in one direction and 'in' in the other else if ( (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && xi[1] <= abs(1. - xi[0]) + tol && xi[1] >= 0. - tol) || (sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third)) && xi[0] <= 1. + tol && xi[0] >= 0. - tol)) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } } } // for (int i=0; i<nseg; ++i) // check whether the bestseg/bestdist are inside that segment // (with some tolerance of 20%) bool ok = false; if (IsOneDimensional()) { if (abs(bestdist[0]) < 1.1) ok = true; } else { if (bestdist[0] <= 1. + tol && bestdist[1] <= abs(1. - bestdist[0]) + tol && bestdist[0] >= 0. - tol && bestdist[1] >= 0. - tol) ok = true; } if (ok) // the projection is good { // build the interpolated normal and overwrite the mnode normal with -n int nsnode = bestseg->Nnode(); MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** snodes = bestseg->Nodes(); std::vector<double> val(nsnode); bestseg->EvaluateFunction(0, bestdist, &val[0], nsnode, NULL); double NN[3]; NN[0] = NN[1] = NN[2] = 0.0; for (int i = 0; i < nsnode; ++i) { const double* Normal = snodes[i]->Normal(); for (int j = 0; j < 3; ++j) NN[j] -= val[i] * Normal[j]; } val.clear(); mnode->SetN(NN); // create projected node and store it in mnode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, bestdist, bestseg); mnode->SetProjectedNode(pnode); mnode->SetGap(bestgap); } else // this mnode does not have a valid projection { if (OutLevel() > 6) std::cout << "MoertelT: ***WRN***: Projection m->s: Node " << mnode->Id() << " does not have projection\n"; mnode->SetProjectedNode(NULL); } } // for (scurr=rnode_[mside].begin(); scurr!=rnode_[mside].end(); ++scurr) // loop all master nodes again and make the projection and the new normal // redundant int bsize = 7 * rnode_[mside].size(); std::vector<double> bcast(bsize); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (proc != NodePID(mnode->Id())) continue; // cannot have a projection on a node i don't own Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode = mnode->GetProjectedNode(); if (pnode == Teuchos::null) continue; // this node does not have a projection const double* xi = pnode->Xi(); const double* Normal = mnode->Normal(); bcast[blength] = (double)pnode->Id(); ++blength; if (pnode->Segment()) bcast[blength] = (double)pnode->Segment()->Id(); else bcast[blength] = -0.1; ++blength; bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = Normal[0]; ++blength; bcast[blength] = Normal[1]; ++blength; bcast[blength] = Normal[2]; ++blength; bcast[blength] = pnode->Gap(); ++blength; } if (blength > bsize) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; double sid = bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; double* n = &bcast[i]; ++i; ++i; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = GetNodeView(nid); Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = Teuchos::null; if (sid != -0.1) seg = GetSegmentView((int)sid); if (mnode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:" "\n" << "***ERR*** Cannot get view of node\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } mnode->SetN(n); MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, xi, seg.get()); mnode->SetProjectedNode(pnode); mnode->SetGap(gap); } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Mismatch in dimension of recv buffer\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); return true; }
InterfaceT)::ProjectNodes_SlavetoMaster_NormalField() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all nodes of the slave side and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; if (NodePID(snode->Id()) != lcomm_->getRank()) continue; const double* sx = snode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode = Teuchos::null; // find a node on the master side, that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; const double* mx = mnode->XCoords(); // build distance | mnode->XCoords() - snode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist <= mindist) { mindist = dist; closenode = mnode; } std::cout << "snode " << snode->Id() << " mnode " << mnode->Id() << " mindist " << mindist << " dist " << dist << std::endl; } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Weired: for slave node " << snode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } #if 0 std::cout << "snode " << *snode; std::cout << "closenode " << *closenode; #endif // get segments attached to closest node cnode int nseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments(); // create a projection-iterator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // finding a good geometric projection is somehow // critical. We work with some tolerance here and pick the 'best' // out of all acceptable projections made // loop these segments and project onto them along snode's normal vector double bestdist[2]; double gap, bestgap = 0.0; const double tol = 0.2; bestdist[0] = bestdist[1] = 1.0e+20; MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL; for (int i = 0; i < nseg; ++i) { // project the slave node onto that master segment double xi[2]; xi[0] = xi[1] = 0.0; projector.ProjectNodetoSegment_NodalNormal(*snode, *(segs[i]), xi, gap); // check whether xi is better then previous projections if (IsOneDimensional()) // 2D case { if (abs(xi[0]) < abs(bestdist[0])) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } else // 3D case { double third = 1. / 3.; // it's 'inside' with some tolerance if (xi[0] <= 1. + tol && xi[1] <= abs(1. - xi[0]) + tol && xi[0] >= 0. - tol && xi[1] >= 0. - tol) { // it's better in both directions if (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third))) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } // it's better in one direction and 'in' in the other else if ( (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && xi[1] <= abs(1. - xi[0]) + tol && xi[1] >= 0. - tol) || (sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third)) && xi[0] <= 1. + tol && xi[0] >= 0. - tol)) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } } } // for (int i=0; i<nseg; ++i) // check whether the bestseg and bestdist are inside the segment // (with some tolerance of 20%) bool ok = false; if (IsOneDimensional()) { if (abs(bestdist[0]) < 1.2) ok = true; } else { if (bestdist[0] <= 1. + tol && bestdist[1] <= abs(1. - bestdist[0]) + tol && bestdist[0] >= 0. - tol && bestdist[1] >= 0. - tol) ok = true; } if (ok) // the projection is good { // create a projected node and store it in snode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, bestdist, bestseg); snode->SetProjectedNode(pnode); snode->SetGap(bestgap); } else { if (OutLevel() > 6) std::cout << "MoertelT: ***WRN***: Projection s->m: Node " << snode->Id() << " does not have projection\n"; snode->SetProjectedNode(NULL); } } // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr) lcomm_->barrier(); // loop all slave nodes again and make the projections redundant std::vector<double> bcast(4 * rnode_[sside].size()); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; if (proc != NodePID(snode->Id())) continue; // I cannot have a projection on a node not owned by me Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode = snode->GetProjectedNode(); if (pnode == Teuchos::null) continue; // this node does not have a projection const double* xi = pnode->Xi(); bcast[blength] = (double)pnode->Id(); ++blength; if (pnode->Segment()) bcast[blength] = (double)pnode->Segment()->Id(); else bcast[blength] = -0.1; // indicating this node does not have // projection but lagrange multipliers ++blength; bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = pnode->Gap(); ++blength; } if (blength > (int)(4 * rnode_[sside].size())) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; double sid = bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = GetNodeView(nid); Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = Teuchos::null; if (sid != -0.1) seg = GetSegmentView((int)sid); if (snode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:" "\n" << "***ERR*** Cannot get view of node\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, xi, seg.get()); snode->SetProjectedNode(pnode); snode->SetGap(gap); } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Mismatch in dimension of recv buffer\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); lcomm_->barrier(); #if 1 // Postprocess the projections // The slave side of the interface might be larger then the master side // of the interface so not all slave nodes have a projection. // For those slave nodes without a projection attached to a slave segment // which overlaps with the master side, Lagrange multipliers have to be // introduced. This is done by checking all nodes without a projection // whether they are attached to some slave segment on which another node // HAS a projection. If this case is found, a pseudo ProjectedNode is // introduced for that node. for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; // don't do anything on nodes that already have a projection if (snode->GetProjectedNode() != Teuchos::null) continue; // get segments adjacent to this node int nseg = snode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = snode->Segments(); // loop segments and check for other nodes with projection bool foundit = false; for (int i = 0; i < nseg; ++i) { int nnode = segs[i]->Nnode(); MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** nodes = segs[i]->Nodes(); for (int j = 0; j < nnode; ++j) if (nodes[j]->GetProjectedNode() != Teuchos::null) if (nodes[j]->GetProjectedNode()->Segment()) { foundit = true; break; } if (foundit) break; } if (foundit) { #if 1 std::cout << "Node without projection:\n" << *snode; std::cout << "...get's lagrange multipliers\n\n"; #endif MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, NULL, NULL); snode->SetProjectedNode(pnode); snode->SetGap(0.); } } // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr) #endif return true; }
// This will paste an array of source nodes into the edit region void CEditClipboard::PasteNodes(CEditRegion *pRegion, CMoArray<CWorldNode*> &sourceArray, PreActionList &undoList, BOOL bPasteAtMarker) { pRegion->ClearSelections(); if (sourceArray.GetSize() <= 0) { ASSERT(FALSE); return; } // Turn off the drawing of the node view if (GetProjectBar()->m_pVisibleDlg == GetNodeView()) { GetNodeView()->SetRedraw(FALSE); } // Set the wait cursor GetNodeView()->BeginWaitCursor(); // Get the active parent node CWorldNode *pActiveParent=pRegion->GetActiveParentNode(); // Calculate the upper left position of all of the bounding box enclosing all // of the nodes as they would appear in DEdit. CVector vBoundingPos; vBoundingPos.x=0.0f; vBoundingPos.y=0.0f; vBoundingPos.z=0.0f; if (bPasteAtMarker) { // Set the initial bounding position int i; for( i=0; i < sourceArray.GetSize(); i++ ) { if (sourceArray[i]->GetType() != Node_Null) { vBoundingPos=sourceArray[i]->GetUpperLeftCornerPos(); break; } } // Find the upper left bounding position for( i=0; i < sourceArray.GetSize(); i++ ) { // Skip Null nodes if (sourceArray[i]->GetType() == Node_Null) { continue; } CVector vUpperLeftCorner=sourceArray[i]->GetUpperLeftCornerPos(); if (vUpperLeftCorner.x < vBoundingPos.x) { vBoundingPos.x=vUpperLeftCorner.x; } if (vUpperLeftCorner.y > vBoundingPos.y) { vBoundingPos.y=vUpperLeftCorner.y; } if (vUpperLeftCorner.z > vBoundingPos.z) { vBoundingPos.z=vUpperLeftCorner.z; } } } int i; for( i=0; i < sourceArray.GetSize(); i++ ) { // Create the new node CWorldNode *pNewNode = sourceArray[i]->AllocateSameKind(); ClipboardDuplicate( sourceArray[i], pNewNode, pRegion ); // Move the node to the marker if (bPasteAtMarker) { // Move brush nodes if(pNewNode->GetType() == Node_Brush) { // Get the brush pointer... CEditBrush *pBrush = pNewNode->AsBrush(); ASSERT(pBrush); // The offset to move the brush from the marker (used when multiple objects are pasted) CVector vMoveOffset=pBrush->GetUpperLeftCornerPos()-vBoundingPos; pBrush->MoveBrush(pRegion->m_vMarker+vMoveOffset); } else if((pNewNode->GetType() == Node_Object) || (pNewNode->GetType() == Node_PrefabRef)) { // The offset to move the object from the marker (used when multiple objects are pasted) CVector vMoveOffset=pNewNode->GetUpperLeftCornerPos()-vBoundingPos; // Handle movement for object nodes... pNewNode->SetPos(pRegion->m_vMarker+vMoveOffset); } } pRegion->AttachNode( pNewNode, pActiveParent ); undoList.AddTail(new CPreAction(ACTION_ADDEDNODE, pNewNode)); } // Make sure the poly texture strings are in the right StringHolder. pRegion->UpdateTextureStrings(); CopyParenthood( sourceArray, pRegion->m_Selections ); pRegion->CleanupGeometry(); ASSERT(pRegion->CheckNodes() == NULL); // Turn on the drawing of the node view if (GetProjectBar()->m_pVisibleDlg == GetNodeView()) { GetNodeView()->SetRedraw(TRUE); GetNodeView()->Invalidate(); } // Generate unique names for the nodes if needed COptionsClipboard *pOptions=GetApp()->GetOptions().GetClipboardOptions(); if (pOptions && pOptions->GetGenerateUniqueNames()) { // Get the document CRegionDoc *pDoc=GetActiveRegionDoc(); // Get the region view POSITION pos = pDoc->GetFirstViewPosition(); CRegionView* pView = (CRegionView *)pDoc->GetNextView( pos ); if(!pView) { ASSERT(FALSE); return; } // Generate unique names pView->GenerateUniqueNamesForSelected(pOptions->GetUpdateRefProps(), TRUE, pOptions->GetDisplayNameChangeReport(), FALSE); // Update the properties dialog pDoc->SetupPropertiesDlg(FALSE); // Redraw all of the views pDoc->RedrawAllViews(); } // Turn off the wait cursor GetNodeView()->EndWaitCursor(); }
// This gets called when the "hide" button is pressed void CProjectTabControlBar::OnButtonHide() { HWND hBar=GetSafeHwnd(); // Get the project bar CProjectBar *pProjectBar=GetMainFrame()->GetProjectBar(); // Get the frame window CFrameWnd* pFrameWnd = (CFrameWnd*)m_pDockSite; //GetParentFrame(); ASSERT(pFrameWnd); // Make sure that the control bar gets hidden if (!pProjectBar->IsFloating()) { pFrameWnd->ShowControlBar(this, FALSE, FALSE); } // Properties dialog if (hBar == GetPropertiesDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_PROPERTIESVIEW); return; } // Class dialog else if (hBar == GetClassListDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_CLASSVIEW); return; } // Texture dialog else if (hBar == GetTextureDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_TEXTUREVIEW); return; } // Model dialog else if (hBar == GetModelDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_MODELVIEW); return; } // Worlds dialog else if (hBar == GetWorldsDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_WORLDSVIEW); return; } // Sound dialog else if (hBar == GetSoundDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_SOUNDVIEW); return; } // Sprite dialog else if (hBar == GetSpriteDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_SPRITEVIEW); return; } // Nodeview dialog else if (hBar == GetNodeView()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_NODESVIEW); return; } else if (hBar == GetPrefabDlg()->GetSafeHwnd()) { pFrameWnd->FloatControlBar(this, CPoint(0,0)); pProjectBar->DockTab(this, CMainFrame::CB_PREFABVIEW); return; } CMRCSizeControlBar::OnButtonHide(); }