iCAx开思工具箱

标题: CAA中利用CATNavigation3DViewer预览装配组件的问题 [打印本页]

作者: chengongcumt    时间: 2005-9-21 14:47
标题: CAA中利用CATNavigation3DViewer预览装配组件的问题
CAA中利用CATNavigation3DViewer可以预览零件模型。想用它来显示装配组件,已经由piProductOnRoot获得了各个零件的CATIProduct_var piProductOnProduct,然后调用piProductOnProduct->GetShapeRep(spLinkableOnShapeRep),再由spLinkableOnShapeRep获得了各个零件实例的CAT3DRep * p3DRep;然后调用_p3DViewer->AddRep( p3DRep);各个零件的p3DRep加入后,最后调用_p3DViewer->Draw();但是却得不到正确的显示结果,不知为什么?而由CAT3DBoundingSphere pBe = p3DRep->GetBoundingElement();获得的CAT3DBoundingSphere 是正确的,可以看到各个零件的CAT3DBoundingSphere半径。请高手指点!!谢谢!!
作者: chengongcumt    时间: 2005-9-21 14:51
还望acoka、saeba、xyzhu等CAA高手给予指点!不胜感激!!
作者: saeba    时间: 2005-9-21 16:29
建议先看一下我的帖子‘提问的技巧’
然后请告诉大家,“得不到正确的显示结果”到底是得到了什么结果?

不仅仅是针对chengongcumt,而是对所有提问的网友们,我想说;

除非有人正好经历过和你一样的问题,才能猜出你大概弄错了什么。
大凡这种问题,90%是你的code哪里出了错,但是如果你不给人家看而是让人家猜,
恐怕除非有大奖,没有人会有兴趣参加。
所以,请贴出你的code,尽量详细,最好能给出直接可用的workspace,因为出于CAA的复杂性,
为了check你的问题,别人不得不从头做很多东西,没有特殊的原因,很少会有人愿意浪费这个时间。
在这里回答问题的网友,我想很多不仅仅是因为热爱技术,而是为了解闷儿,如果你的问题只能使人更闷,
结果可想而知。
作者: chengongcumt    时间: 2005-9-22 09:32
谢谢saeba指导!获益匪浅!下面是CODE,请指导!
int ViewTestCmd:isPlayCatiaModel(CATUnicodeString DocumentName)
{         
        if (NULL!= _pTheModelToDisplay)//_pTheModelToDisplayOld
        {       
                _p3DViewer->RemoveRep (_pTheModelToDisplay);       
                //        _p3DViewer在"ViewTestCmd.h"中定义过CATNavigation3DViewer* _p3DViewer;
        }

        HRESULT rc;
        CATUnicodeString oName ;
        cout <<"Importing an existing CATProduct under the root product"<<endl;
        //1.打开文档
        CATDocument *pDoc= NULL;  
        rc = CATDocumentServices::Open(DocumentName,pDoc);        ///DocumentName为要显示的装配文档
        if ( FAILED(rc) || (NULL==pDoc) )
        {
                cout <<"opening a CATProduct document failed"<<endl;
                return 1;
        }               
        // 2.获取根产品:
        CATIDocRoots *piDocRootsOnDoc = NULL;
        rc = pDoc->QueryInterface(IID_CATIDocRoots,(void**) &piDocRootsOnDoc);
        if ( FAILED(rc) )
        {
                cout <<"access to the root product failed"<<endl;
                return 2;
        }
  
        CATListValCATBaseUnknown_var *pRootProducts=piDocRootsOnDoc->GiveDocRoots();
        CATIProduct_var spRootProduct = NULL_var;
        if (NULL != pRootProducts)
        {
                if (pRootProducts->Size())
                {  
                        spRootProduct = (*pRootProducts)[1];
                        delete pRootProducts;
                        pRootProducts = NULL;
                }
        }
        else
        {
                cout<<"NULL != pRootProducts"<<endl;
        }
        piDocRootsOnDoc->Release();
        piDocRootsOnDoc        =NULL;

        if (NULL_var == spRootProduct)
        {
                cout << " ERROR: No root product !!  " << endl << flush;
                return 3;
        }       
        CATIProduct_var piProductOnRoot = NULL_var;

        rc = spRootProduct->QueryInterface(IID_CATIProduct,
                                                                           (void**) &piProductOnRoot);
        if ( FAILED(rc) )
        {
                cout<< "QueryInterface IID_CATIProduct failed !"<<endl;
                return 4;
        }
        else
        {
                ////最终得到了piProductOnRoot
                piProductOnRoot->GetPrdInstanceName(oName);
                cout<<"pCurrentProduct InstanceName:"<<oName.ConvertToChar()<<endl;
        }
       
        CATListValCATBaseUnknown_var* pProductList = piProductOnRoot->GetAllChildren();
        int numberOfProducts = pProductList->Size();
        cout<<"pProductList->Size():"<<numberOfProducts<<endl;
       
        //3.获取形状描述
        CATILinkableObject_var spLinkableOnShapeRep = NULL_var;

        if (SUCCEEDED(piProductOnRoot->GetShapeRep(spLinkableOnShapeRep)))  
        {
                cout<<"piProductOnRoot GetShapeRep Succeed!!"<<endl;
        }
        else
        {
                cout<<"piProductOnRoot GetShapeRep Failed!!"<<endl;

        }

        CATVisManager* pVisManager = CATVisManager::GetVisManager();
        if ( NULL == pVisManager )
        {
                cout <<" ERROR by retrieving the CATVisManager instance" << endl;               
                return 5;
        }
       
        for (int i = 1;  i <= numberOfProducts; i++)
        {               
                CATIProduct* piProductOnProduct = NULL;        
                if (SUCCEEDED((*pProductList)[i]->QueryInterface(IID_CATIProduct,(void**)&piProductOnProduct)))        
                {                           
                        if (SUCCEEDED(piProductOnProduct->GetShapeRep(spLinkableOnShapeRep)))  
                        {
                               
                                cout<<"GetShapeRep Succeed!!"<<endl;
                                CATPathElement* RootObjectPath=new CATPathElement(spLinkableOnShapeRep);
                               
                                ///------------------------------------------------------
                                list<IID> ListIVisu3d;
                                IID visu3d = IID_CATI3DGeoVisu ;
                                ListIVisu3d.fastadd(&visu3d);
                                CAT3DViewpoint * pVP = new CAT3DViewpoint();   
                                ///将上面四行代码放至FOR循环前面,则可显示装配中的两个零件,
                                //但加入两个零件后AttachTo方法失效
                                               
                                rc = pVisManager->AttachTo ( RootObjectPath, pVP, ListIVisu3d);                               

                                if ( FAILED(rc) )
                                {
                                        cout <<" ERROR in the AttachTo method" << endl;
                                        return 6;
                                }  
                                CATI3DGeoVisu * pIVisuOnRoot =NULL ;   
                                rc = spLinkableOnShapeRep->QueryInterface(IID_CATI3DGeoVisu,
                                                                                                                                          (void **) & pIVisuOnRoot);
                                if ( SUCCEEDED(rc) )
                                {
                                  
                                   CATRep * pRep = pIVisuOnRoot->GiveRep();
                                   if ( NULL != pRep )
                                   {
                                          CAT3DRep * p3DRep = (CAT3DRep *) pRep;                         
                                         _pTheModelToDisplay=(CAT3DBagRep *)p3DRep;
                                          CAT3DBoundingSphere pBe = p3DRep->GetBoundingElement();
                                          float radius = pBe.GetRadius();
                                          cout <<" The radius of the bounding box = " << radius << endl;
         
                                   }
                                        pIVisuOnRoot->Release();
                                        pIVisuOnRoot = NULL ;
                                }
                                else
                                {
                                        cout <<" ERROR to retrieve the CATI3DGeoVisu interface" << endl;               
                                        return 7;
                                }
                                if ( (NULL != _p3DViewer)  && ( NULL != _pTheModelToDisplay))   
                                {                                       
                                        _p3DViewer->AddRep((CAT3DRep*)_pTheModelToDisplay);                                                                                               
                                }
                        }
                }
        }
               
        ///4.显示模型
   

    if ( NULL != _p3DViewer)
        {
                _p3DViewer->Draw();       
                cout<<"_p3DViewer->Draw()!!"<<endl;
        }
                //pVisuManager->DetachFrom(_pRootObjectPath, pVP);

                //CATDlgNotify * pPromptBox = new CATDlgNotify((CATApplicationFrame::GetApplicationFrame())->GetMainWindow(), "Right", CATDlgNfyInformation);  
                //pPromptBox->SetTitle(pOccurringError->GetNLSSource());
                //pPromptBox->SetText("All have been down,ok!!!");  
                //pPromptBox->SetVisibility(CATDlgShow);       
       
        else
        {
                cout<<"(NULL == _p3DViewer)  Failed!!"<<endl;
                return 8;
        }
        rc = CATDocumentServices::Remove (*pDoc);
        if ( FAILED(rc) )
        {
                cout <<"Deleting the *pDoc failed"<<endl;
                return 9;
        }
        return 0;
}
作者: chengongcumt    时间: 2005-9-22 11:48
以下是程序的WORKSPACE文档,请指导!谢谢!!
作者: chengongcumt    时间: 2005-9-22 11:54
--------------------------------------------------------------------------------
以下是程序的WORKSPACE文档,请指导!谢谢!!
作者: chengongcumt    时间: 2005-9-22 11:55
--------------------------------------------------------------------------------
以下是程序的WORKSPACE文档,请指导!谢谢!!
作者: chengongcumt    时间: 2005-9-22 11:56
--------------------------------------------------------------------------------
以下是程序的WORKSPACE文档,请指导!谢谢!!
作者: saeba    时间: 2005-9-22 12:06
Very good! You are doing a perfect example!
Could you also tell me the structre of your main product (tree view)?
Anyway, I will look at your code next week.
I have to prepare a training this week, thank you for your understanding.
作者: chengongcumt    时间: 2005-9-22 15:02
由于要显示的Product的产品树较大,我将要预览显示的装配文件也发上去吧,其实随便用一个装配文件都可以。谢谢saeba!!祝一切顺利!!
作者: chengongcumt    时间: 2005-9-26 08:31
有没有哪位CAA高手能帮忙看看啊?谢谢!saeba兄最近还很忙呢吧。
作者: saeba    时间: 2005-9-26 16:19
今天终于找时间看了一下,还没有解决所有问题,但是知道了为什么AttachTo会失败:
其实AttachTo并不是从第4个以后就都失败的,
如果你把
                                                cout <<" ERROR in the AttachTo method" << endl;
                                                return 6;
改成
                                                cout <<" ERROR in the AttachTo method" << endl;
                                                continue;
就会发现,对有些子product是成功的,为什么呢?
仔细看看成功的和失败的,发现,
虽然你的父product下面虽然有42个子product,但是其实有很多都是重复的指向同一个catpart
成功的AttachTo都是对不同的catpart,而失败的都是对已经AttachTo过的
因此,如果你把
CATPathElement* RootObjectPath=new CATPathElement(spLinkableOnShapeRep);
改成
CATPathElement* RootObjectPath=new CATPathElement(piProductOnProduct);
就一个也不会失败了,因为每个子product都是不同的

但是问题仍然没有解决,AttachTo虽然没有失败,但viewer上面并没有显示
原因我也不知道...
作者: chengongcumt    时间: 2005-9-26 17:57
非常感谢saeba!不好意思占用你的宝贵时间了,不知该说什么了,还是谢谢!
作者: chengongcumt    时间: 2005-9-26 18:16
实际上,我把spLinkableOnShapeRep类型改为CATISpecObject_var时,AttachTo也不失效了,但也是不显示,不知为什么?急啊!还请大家有时间再帮忙看看。有关代码如下:
        CATISpecObject_var spLinkableOnShapeRep = NULL_var;
        //CATILinkableObject_var spLinkableOnShapeRep = NULL_var;
        CATVisManager* pVisManager = CATVisManager::GetVisManager();
        if ( NULL == pVisManager )
        {
                cout <<" ERROR by retrieving the CATVisManager instance" << endl;               
                return 5;
        }

        list<IID> ListIVisu3d;
        IID * visu3d =new IID(IID_CATI3DGeoVisu );
        ListIVisu3d.fastadd(visu3d);
        CAT3DViewpoint * pVP = new CAT3DViewpoint();
       
        int NumOfInstanceParts=0;                       
        for (int i = 1;  i <= numberOfProducts; i++) //
        {               
                CATIProduct* piProductOnProduct = NULL;        
                if (SUCCEEDED((*pProductList)[i]->QueryInterface(IID_CATIProduct,(void**)&piProductOnProduct)))        
                {                           
                        if (SUCCEEDED(piProductOnProduct->QueryInterface(IID_CATISpecObject,(void**)&spLinkableOnShapeRep)))  
                        //if (SUCCEEDED(piProductOnProduct->GetShapeRep(spLinkableOnShapeRep)))
                        {
                                NumOfInstanceParts=NumOfInstanceParts+1;
                                cout<<"GetShapeRep Succeed!!"<<endl;                       
                                CATPathElement* RootObjectPath=new CATPathElement(spLinkableOnShapeRep); //piProductOnProductspLinkableOnShapeRep//piProductOnRoot  
                                ///------------------------------------------------------
                       
                                //list<IID> ListIVisu3d;
                                //IID visu3d = IID_CATI3DGeoVisu ;
                                //ListIVisu3d.fastadd(&visu3d);
                                //CAT3DViewpoint * pVP = new CAT3DViewpoint();                                
                                               
                                rc = pVisManager->AttachTo ( RootObjectPath, pVP, ListIVisu3d);                               

                                if ( FAILED(rc) )
                                {
                                        cout <<" ERROR in the AttachTo method" << endl;
                                        return 6;
                                }
                                CATI3DGeoVisu * pIVisuOnRoot =NULL ;   
                                rc = spLinkableOnShapeRep->QueryInterface(IID_CATI3DGeoVisu, (void **) & pIVisuOnRoot);
                                CAT3DRep * p3DRep=NULL;                                                                                                         
                                if ( SUCCEEDED(rc) )
                                {
                                  
                                   CATRep * pRep = pIVisuOnRoot->GiveRep();
                                   if ( NULL != pRep )
                                   {
                                          p3DRep = (CAT3DRep *) pRep;                         
                                         _pTheModelToDisplay=(CAT3DBagRep *)p3DRep;                                       
                                        _pTheModelToDisplay->AddChild(*pRep);
                                          CAT3DBoundingSphere pBe = p3DRep->GetBoundingElement();
                                          float radius = pBe.GetRadius();
                                          cout <<" The radius of the bounding box = " << radius << endl;
         
                                   }
                                        pIVisuOnRoot->Release();
                                        pIVisuOnRoot = NULL ;
                                }
                                else
                                {
                                        cout <<" ERROR to retrieve the CATI3DGeoVisu interface" << endl;               
                                        return 7;
                                }
                               
                                //pVisManager->DetachFrom(RootObjectPath, pVP);
                        }
                }
        }
        cout<<"发现零件实例数目:"<<NumOfInstanceParts<<endl;
if ( NULL != _p3DViewer)
        {
                _pTheModelToDisplay->SetShowMode (1,1);
                _p3DViewer->AddRep((CAT3DRep *) _pTheModelToDisplay);
               
                _p3DViewer->Draw();        _pTheModelToDisplay->SetShowMode (1,1);
                cout<<"_p3DViewer->Draw()!!"<<endl;
        }
.......
作者: cms_nuaa    时间: 2005-9-26 19:24
不知道你的组件是不是装配好了的。如果是已经装配好的话,它的预览显示并不需要得到所有的子零件或者子Product,它的显示与零件的预览是类似的。怀疑你走入了误区~~
作者: xyzhu    时间: 2005-9-26 20:03
你在循环里用了 rc = pVisManager->AttachTo ( RootObjectPath, pVP, ListIVisu3d);然后在循环外用了_p3DViewer->AddRep((CAT3DRep *) _pTheModelToDisplay); 这两个重复了. 试试删除AttachTo那句.
还有,AddRep是"Adds a representation 3D in the Main 3D Viewpoint", 那个Main 3D Viewpooint是通过CATViewer::GetMain3DViewpoint()得到的, 你用了new CAT3DViewpoint, 也许这也会产生问题.
作者: chengongcumt    时间: 2005-9-27 08:59
谢谢cms_nuaa、xyzhu !

xyzhu兄提供的思路试过了,可还是不行啊,不知问题到底在哪里?
组建是装配好 的,不知cms_nuaa说的直接显示如何实现,好象是一个不错的思路。我最初也曾想直接显示装配体:
if (SUCCEEDED(piProductOnRoot->GetShapeRep(spLinkableOnShapeRep)))  
        {
                cout<<"piProductOnRoot GetShapeRep Succeed!!"<<endl;
        }
        else
        {
                cout<<"piProductOnRoot GetShapeRep Failed!!"<<endl;

        }
但是好象不直接与零件相关的Product就不能得到GetShapeRep的结果。不知如何构造装配体的CAT3DRep *描述,以便用CAT3DViewer或CATNavigation3DViewer显示。请cms_nuaa指教!谢谢!!
作者: saeba    时间: 2005-9-27 10:11
好消息,我想是解决了!

一个一个来,
首先,为什么return 6改成continue以后就没了显示,
今天仔细看了看,原来你在之后,作了document的remove:
rc = CATDocumentServices::Remove (*pDoc);
这样一来,整个product的信息全部从session中删除,自然也就没了显示
把这个remove注释掉,果然显示就出来了。
但是这时的显示,因为没有matrix信息,看起来就像只有一个part被显示了一样。

那么怎么显示实际的装配图呢?
有两个方法,
1。直接显示主product,这时根本就不用循环了
                                ...
                                CATPathElement* RootObjectPath=new CATPathElement(spRootProduct);
                               
                                        rc = pVisManager->AttachTo(RootObjectPath, pVP, ListIVisu3d, NULL, 0, 1);                               

                                        if ( FAILED(rc) )
                                        {
                                                cout <<" ERROR in the AttachTo method" << endl;
                                                return 6;
                                        }else{
                                                cout << "AttachTo OK." << endl;
                                        }

                                        CATI3DGeoVisu * pIVisuOnRoot =NULL ;   
                                        rc = spRootProduct->QueryInterface(IID_CATI3DGeoVisu, (void **) & pIVisuOnRoot);
                                        ...
就可以

2。如果你想控制其中的几个子product不显示或别的什么,
不必用piProductOnProduct->GetShapeRep(spLinkableOnShapeRep) (循环还是要的)
而是:
在循环中
                                ...
                                CATPathElement* RootObjectPath=new CATPathElement(piProductOnProduct);
                               
                                        rc = pVisManager->AttachTo(RootObjectPath, pVP, ListIVisu3d, NULL, 0, 1);                               

                                        if ( FAILED(rc) )
                                        {
                                                cout <<" ERROR in the AttachTo method" << endl;
                                                continue;
                                        }else{
                                                cout << "AttachTo OK." << endl;
                                        }

                                        CATI3DGeoVisu * pIVisuOnRoot =NULL ;   
                                        rc = piProductOnProduct->QueryInterface(IID_CATI3DGeoVisu, (void **) & pIVisuOnRoot);
                                ...

都会得到附图的结果
作者: saeba    时间: 2005-9-27 10:14
>但是好象不直接与零件相关的Product就不能得到GetShapeRep的结果。不知如何构造装配体的CAT3DRep *描述,以便用CAT3DViewer或CATNavigation3DViewer显示

根本不必GetShapeRep,product直接就可以QI到CATI3DGeoVisu。
查查Object Browser就知道了
作者: chengongcumt    时间: 2005-9-27 11:26
非常感谢Saeba!我上午也发现这个问题了,其实好像还有更简单的方法:
spSpecObjectPart=piProductOnRoot;//零件用pSpecContainer->GetPart();
       
        //组件--------------------------------------------------------------
        if(spSpecObjectPart==NULL_var)
        {
                cout<<"spSpecObjectPart==NULL_var!"<<endl;
                return 5;
        }
        CATPathElement* RootObjectPath=new CATPathElement(spSpecObjectPart);
接下来就和零件显示一样了。
谢谢!祝顺利!
作者: cms_nuaa    时间: 2005-9-27 12:50
呵呵,不错~~

saeba 兄诲人不倦,很佩服~~
作者: qoop    时间: 2007-11-5 02:49
这个不错!
作者: mercury0504    时间: 2008-3-14 15:03
恩? 怎么看不到附件
作者: 圈圈眉    时间: 2014-4-23 16:52
这个贴不错,普及了这块呀!




欢迎光临 iCAx开思工具箱 (https://t.icax.org/) Powered by Discuz! X3.3