/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/GelPosition.h" #include "topo/Shell.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // //Implements MGGelPosition Class. //MGGelPosition is a class which expresses which group a gel belongs to. // ///Void constructor. MGGelPosition::MGGelPosition():m_group(0),m_agel(0), m_object(0){ } ///Constructor of no hierarched group(m_Ghierarcy.size()==0). MGGelPosition::MGGelPosition(MGGroup* group, MGObject* obj) :m_group(group),m_agel(obj), m_object(obj){ } ///Copy constructor. MGGelPosition::MGGelPosition(const MGGelPosition& gelp2) :m_group(gelp2.m_group),m_agel(gelp2.m_agel), m_object(gelp2.m_object), m_Ghierarcy(gelp2.m_Ghierarcy){ } //Assignment. MGGelPosition& MGGelPosition::operator=(const MGGelPosition& gelp2){ m_group=gelp2.m_group; m_agel=gelp2.m_agel; m_object=gelp2.m_object; m_Ghierarcy=gelp2.m_Ghierarcy; return *this; } //Equal operator bool MGGelPosition::operator==(const MGGelPosition& gelp2) const{ if(m_group!=gelp2.m_group) return false; if(m_agel!=gelp2.m_agel) return false; if(m_object!=gelp2.m_object) return false; size_t n1=m_Ghierarcy.size(), n2=gelp2.m_Ghierarcy.size(); if(n1!=n2) return false; for(size_t i=0; in1) return false; if(n1>n2) return true; for(size_t i=0; igroup() || gel->shell()); m_Ghierarcy.push_back(gel); } //Get the lowerest level of group pointer of this. const MGGroup* MGGelPosition::bottom_group_sub()const{ const MGGroup* grp=m_group; int nhierk=(int)m_Ghierarcy.size(); if(nhierk--){ const MGGel* gel=m_Ghierarcy[nhierk--]; const MGGroup* grp2=dynamic_cast(gel); if(grp2) grp=grp2; else{ if(nhierk>=0){ gel=m_Ghierarcy[nhierk]; grp=static_cast(gel);; } } } return grp; } ///Get the group pointer. const MGGroup* MGGelPosition::bottom_group()const{ return bottom_group_sub(); } MGGroup* MGGelPosition::bottom_group(){ const MGGroup* grp=bottom_group_sub(); return const_cast(grp); } //Generate a newed clone object. MGGelPosition* MGGelPosition::clone()const{ return new MGGelPosition(*this); } ///Test if this is null. bool MGGelPosition::is_null()const{ if(m_Ghierarcy.size()) return false; return m_agel==0; } //Get the shell pointer when this is_shell_face() is true. //When is_shell_face() is false, behavior is undefined. MGShell* MGGelPosition::get_shell_of_shell_face()const{ assert(m_Ghierarcy.size()); assert(dynamic_cast(m_object)&& dynamic_cast(m_Ghierarcy.back())); return dynamic_cast(m_Ghierarcy.back()); } ///Test if this MGGelPosition is a member of a group of the input grp. ///Test is done through the hierarchy of this gelposition. ///Returned is null if this is not a member of (or a member group of) grp. ///The parent group pointer is returned if grp has a parentgroup. ///If grp does not have parent group, grp will be returned. const MGGroup* MGGelPosition::is_a_member_of(const MGGroup* grp)const{ if(!grp) return 0; const MGGroup* upGrp=m_group; if(grp==upGrp) return upGrp; size_t nhierk=m_Ghierarcy.size(); if(!nhierk) return 0; for(size_t i=0; i(m_Ghierarcy[i]); if(grp2==grp) return upGrp; if(!grp2) return 0; upGrp=grp2; } return 0; } ///Test if this is MGGelpotion that point shell and the member face. ///That is, m_object is MGFace and top_object() is MGShell. bool MGGelPosition::is_shell_face()const{ if(!m_object) return false; if(top_object_sub()==m_object) return false;//Since m_object=MGFace and m_Ghierarcy.back()=MGShell. assert(dynamic_cast(m_object)&& dynamic_cast(m_Ghierarcy.back())) ; return true; } //Test if this is one of the type of types. bool MGGelPosition::is_type(const MGAbstractGels& types)const{ if(leaf_is_group()){ return m_Ghierarcy.back()->type_is(types); } if(is_shell_face()){ const MGObject* obji=top_object(); return obji->type_is(types); } if(!m_agel) return false; return m_agel->type_is(types); } //Test if this leaf is MGGroup. bool MGGelPosition::leaf_is_group()const{ if(m_agel) return false; size_t nhierk=m_Ghierarcy.size(); if(!nhierk) return false; assert(dynamic_cast(m_Ghierarcy.back())) ; return true; } ///Set the leaf object data. void MGGelPosition::set_attribedGel(MGAttribedGel* agel){ m_agel=agel; MGObject* obj=dynamic_cast(agel); if(obj) m_object=obj; else m_object=0; } ///Set the leaf object data. void MGGelPosition::set_leaf_object(MGObject* obj){ m_agel=m_object=obj; } ///Get the target attribed gel to update. ///I.e., if this is shell_face, return the shell. ///Else, return the leaf AttribedGel. MGAttribedGel* MGGelPosition::targetGel(){ MGAttribedGel* agel; if(is_shell_face()){ agel=top_object(); }else agel=static_cast(leafAttribedGel()); return agel; } //Get the object pointer of this. const MGObject* MGGelPosition::top_object_sub()const{ size_t nhierk=m_Ghierarcy.size(); const MGObject* obj=0; if(nhierk) obj=dynamic_cast(m_Ghierarcy[nhierk-1]); if(obj) return obj;//This must be MGShell. return m_object; } const MGObject* MGGelPosition::top_object()const{ return top_object_sub(); } MGObject* MGGelPosition::top_object(){ const MGObject* obj=top_object_sub(); return const_cast(obj); } ///Clear the content. void MGGelPosition::set_null(){ m_group=0; m_Ghierarcy.clear(); m_agel=m_object=0; } //Test if this is symmetric to gel2. //Symmetric means: ///Both leaf objects are MGObject and they have the same manifold dimension. bool MGGelPosition::symmetric(const MGGelPosition& gelp2)const{ const MGObject* obj1=leaf_object(); if(!obj1) return false; const MGObject* obj2=gelp2.leaf_object(); if(!obj2) return false; return (obj1->manifold_dimension()==obj2->manifold_dimension()); } //Perform add operation of this gel position. //(insert the object of m_object in the lowerest level of group). //This is valid only for top_object() is not shell //(unable to add face into shell). void MGGelPosition::do_add(){ MGGroup* group_up; MGGel* gel_to_add; MGGroup* grp=bottom_group(); if(is_shell_face()){ group_up=grp; gel_to_add=top_object(); }else if(leaf_is_group()){ gel_to_add=grp; size_t nhierak=m_Ghierarcy.size(); if(nhierak>=2) group_up=static_cast(m_Ghierarcy[nhierak-2]); else group_up=m_group; }else{ group_up=grp; gel_to_add=m_agel; } group_up->push_back(gel_to_add); } //Perform remove operation of this gel position. //(Release the gel of m_gel from the group of m_group, but does not delete the gel). void MGGelPosition::do_remove(){ MGGroup* group_up; MGGel* gel_to_remove; MGGroup* grp=bottom_group(); if(is_shell_face()){ group_up=grp; gel_to_remove=top_object(); }else if(leaf_is_group()){ gel_to_remove=grp; size_t nhierak=m_Ghierarcy.size(); if(nhierak>=2) group_up=static_cast(m_Ghierarcy[nhierak-2]); else group_up=m_group; }else{ group_up=grp; gel_to_remove=m_object; } MGGroup::reverse_iterator i=group_up->rbegin(), iend=group_up->rend(), inext; while(i!=iend){ inext=i; inext++; if(*i==gel_to_remove){ group_up->release(inext.base());//release the found gel break; } i=inext; } }