1. 程式人生 > >解決ARX自定義實體類viewportDraw顯示問題

解決ARX自定義實體類viewportDraw顯示問題

問題描述:

在自定義實體的viewportDraw裡繪製與檢視相關的顯示,為什麼執行3dorbit(三維動態觀察)時不顯示,退出3dorbit後顯示又正常?

經反覆測試,建立自定義實體後,只要呼叫了修改自定義實體屬性的函式,相應的實體在執行3dorbit命令過程中就不會顯示

Issue

Our custom entity does all its drawing in the ViewportDraw routine, but if you display one of our entities on a 'SHADEMODE' view (Hide/Flat/Gouraud etc.) then the entity does not appear. Changing back to 2D displays the entity properly.  Why doesn't our entity display properly in SHADEMODE?

Solution

There are several problems related to this issue which make this a difficult area to develop with.  These problems are present in AutoCAD 2000i, 2002, 2004, 2005, 2006 and 2007 but not in R2000. 

Here is a summary of them, and a brief description of each workaround, which is demonstrated below:

1) If graphics are created from within viewportDraw() (ie worldDraw() returns false), the kDrawableViewIndependentViewportDraw flag must be set within setAttributes() in order to see any custom entity graphics when in a SHADEMODE other than 2D Wireframe.  This applies not only for viewport-independent graphics, but also for viewport-dependent graphics.  This is related to Change Request 282888 and has been fixed for AutoCAD 2004 upwards.

2)  When in a SHADEMODE other than 2D wireframe, viewportDraw() will be called with the incorrect regenType() intermittently, so that when zooming or panning (among other operations), the graphics will appear to switch at random.  This is Change Request 168103.  A workaround to determine the regenType() manually can be implemented by simply trying to create an AcGsView with acgsGetGsView(), which will fail in 2D shademode, but succeed in any other mode.

Note that acgsGetGsView() is part of the ObjectARX SDK (not ObjectDBX) and therefore care should be taken to get the module handle of acad.exe then get proc address - don't link your DBX to the ObjectARX SDK (See code below)

3)  When in a SHADEMODE other than 2D wireframe, AcGiViewportDraw::viewDir() will always return (0,0,1) when the regenType() is kAcGiRenderCommand (which again is intermittent).  The view direction must be calculated via AcGsView::position() and AcGsView::target().  See code workaround below. This is Change Request 136908.

4)  If while in SHADEMODE the graphics representation is changed (eg from 3d to 2d or vice versa), the 3D graphics queue must be flushed.  Even a Regen command will not always update these graphics, but AcGsView::invalidateCachedViewportGeometry() (or AcGsModel::invalidate()) does this properly.  This is not necessary when SHADEMODE is 2D wireframe.  This is by design, but is not well documented.

Solution to Problem 1 (code)

// Within the custom entity, add the kDrawableViewIndependentViewportDraw flag to 
// the base-class version of setAttributes()...Adesk::UInt32 Cline::setAttributes(AcGiDrawableTraits* pTraits)
{
    
return AcDbEntity::setAttributes(pTraits) | kDrawableViewIndependentViewportDraw;
}

Solution to Problem 2 (code)

// tries to get the gsView from autocad. It's fine to do this in non AutoCAD
// applications because if AutoCAD doesn't exist, we simply don't do anythingAcGsView *GetGsView(AcGiViewportDraw *mode)
{
    
// see if we are running inside of autocad    HMODULE hMod = ::GetModuleHandle(_T("acad.exe"));
    
// if we areif(hMod)
    {
        
// prepare a function pointer to get the AcGsView.        typedef AcGsView* (*exp_acgsGetGsView)(intbool); 
        
// try to get the function pointer to acgsGetGsView        exp_acgsGetGsView funcPtr = (exp_acgsGetGsView)::GetProcAddress(hMod, "[email protected]@[email protected]@[email protected]");
        
// If this was successful, we can assume that we can use it.if(funcPtr)
            
// all ok, return the AcGsViewreturn funcPtr(mode->viewport().acadWindowId(), false);
    }
    
    
return NULL;
}

Solution to Problem 3 (code) 

// function to determine the view direction.AcGeVector3d GetViewDirection(AcGiViewportDraw *mode)
{
    
// try and extract the acgsview    AcGsView *pView = GetGsView(mode);  
    
// if ok and in 3D view - we must calc our own view direction if (pView) 
        
// if 3D view, then we must calc our own... return (pView->position()-pView->target()).normalize(); 
    
else// otherwise, the viewdir must be okreturn mode->viewport().viewDir().normalize();
}
// Here is the overridden viewportDraw() which includes the remaining workarounds...void Cline::viewportDraw(AcGiViewportDraw* mode)

    
// Try to obtain an AcGsView for the current viewport...this will fail if it is a 2D wireframe (normal) view or if not running in AutoCAD
    
// (will set pView to NULL.)    AcGsView *pView = GetGsView(mode); // This will solve problem 2
    
// You can detect if there is a conflict (ie the defect is present) like this:if (pView && mode->regenType() == kAcGiStandardDisplay)
        acutPrintf(
"Conflict in regen type ");
    
    
// This is to workaround Change Request 136908...the viewDir is incorrect for regenType kRenderCommand...
    
// We can calculate the view direction ourselves for a 3D view.  .    AcGeVector3d vDir = GetViewDirection(mode); // This will solve problem 3
    
    
// Draw your graphics here...perhaps they are drawn differently depending on 2D or 3D modes...
    
    
    
// You must invalidate the 3D graphics cache if your graphics change between 2D and 3D modes.  
    
// Perhaps this can be done within an Editor Reactor which detects when the SHADEMODE
    
// command ends, and place the call to invalidateCachedViewportGeometry() there, but of course
    
// that would require ObjectARX. Instead you can place the following code in the viewportDraw()
    
// function, note that it will cause the function to be called twice anytime an update is needed
    
// (This may be a small price to pay however).  if(pView)
    {
        pView
->invalidateCachedViewportGeometry(); // This will solve problem 4
        
        
// The following code also works for this purpose:
        
//AcGsModel *gsModel=acgsGetGsManager()->getDBModel();
        
//gsModel->invalidate(AcGsModel::kInvalidateViewportCache);    }

在此感謝:大海(7098676)、阿 呆  (15983527)等人提供幫助!

相關推薦

解決ARX定義實體viewportDraw顯示問題

問題描述: 在自定義實體的viewportDraw裡繪製與檢視相關的顯示,為什麼執行3dorbit(三維動態觀察)時不顯示,退出3dorbit後顯示又正常? 經反覆測試,建立自定義實體後,只要呼叫了修改自定義實體屬性的函式,相應的實體在執行3dorbit命令過程中就不會顯示

解決雙擊dwg文件ARX定義實體提示代理的問題

efi col style 一個 startup dword req rip app 雙擊dwg文件的時候,如果沒有通過註冊表設置會提示代理實體。 註冊表自動加載arx 註冊表參考路徑 R18.1 是cad版本 ACAD-9001:409 是cad的地區語言,409是英文

EF學習筆記——生成定義實體

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Mybatis需要返回的資料引數中在資料表中沒有對應的欄位,定義實體和resultmap作為返回值型別

自定義實體類:因為需要做相關記錄的統計,而表中沒有統計欄位 public class TrafficJeevesDistrictCount { //施工top5+1 按區域 private String districtInfo; private

SpringBootDataJpa定義查詢返回定義實體

在使用jpa的時候,jpa雖然封裝了大量的crud操作,但是有時也會根據業務需要自定義查詢語句以及返回的自定義實體類 接下來就將一步一步的排坑 電信計費系統: 實體類介紹 費用表實體類 @Entity @Table(name = "t_costs") public cla

Spring JPA 定義實體定義sql語句多表關聯複雜子查詢

   最近在寫一個功能,因為不是很熟悉jpa操作,接觸時間不久,所以又習慣性地用了sql語句來查詢,主要是嫌麻煩,想返回的資料用一條資料返回來就可以了,所以就用spring  jpa寫了個自定義的實體類來裝我專門返回來的資料欄位,然後sql也有點複雜,join了幾張表,

arx 定義實體簡單例項

class DLLIMPEXP MyLineEx : public AcDbEntity { public: ACRX_DECLARE_MEMBERS(MyLineEx) ; protected: static Adesk::UInt32 kCurrentVersi

C# 實現Sort介面 排序定義實體集合

預定義實體類 class SortClass { public SortClass(int id,String value) { this.Id = id;

Hibernate3.1.3使用定義實體實現對SQL查詢語句的對映

Hibernate3.1.3使用自定義實體類實現對映 前言: 在使用Hibernate操作資料庫時, 特別是進行查詢時,往往要使用儲存過程或一些不方便使用實體類對映的SQL語句。這時就要用到hibernate的自定義SQL語句對映類。下面來介紹一下該過程的實現。 1.下載Hibernate3.1.3(比較

ARX定義實體常用虛擬函式explode/worldDraw/transformBy/getOsnapPoints/getGripPoints

ARX自定義實體常用虛擬函式   i.         統一說明- sub/非sub sub開頭函式用於vc90以及上版本繼承函式,對應的不帶sub開頭的為vc80及以下版本繼承函式。 原因是對於vc90以上版本AcGiDrawable/AcDbEntity類: S

Spring Data Jpa框架定義查詢語句返回定義實體解決方案

在使用Spring Data Jpa框架時,根據業務需求我們通常需要進行復雜的資料庫查詢,並返回我們自定義的實體類,而在該框架下,目前僅僅支援返回與資料庫對映進行持久化的POJO實體。雖然在框架上我們可以使用@Query註解執行我們自定義的sql語句,但是其返回值為List<Object[

MapReduce資料傾斜解決方案2-- 定義分割槽---二次作業

資料傾斜:大量資料湧向到一個或者幾個reduce,造成大量的reduce空閒。 解決資料傾斜方案2:自定義分割槽類---二次作業 下面以單次統計為例進行說明: 1、DataLeanMapper1 package hadoop.lean.partitioner; i

Unity在編輯面板顯示定義

public class Boundary { public float xMin, xMax, zMin, zMax; } public class PlayerController : MonoBehaviour { public float speed

Android 百度地圖新增定義marker(覆蓋物)不顯示圖片的解決方法

在使用百度地圖新增自定義Marker View時,顯示不出來自定義marker view裡面的頭像,百度地圖的新增自定義marker顯示網路圖片本身就是一個坑(我是這樣認為的)... 我的需求是這樣的,當有人員上報位置時,就根據經緯度把人員位置資訊用自定義Marker去載入

Java程式設計之TreeSet排序兩種解決方法(1)元素自身具備比較功能,元素需要實現Comparable介面覆蓋compare(2)建立根據定義Person的name進行排序的Comparator

       當很多人問我讀研到底好不好的時候,我總是說上研很苦逼,讀完研之後都不知道自己能不能找到工作,所以不建議同學們讀研~即使要讀也讀一個985或者211的研究生,這是我肺腑之言。但還有一半我沒說完,讀研的時候你可能會找到你喜歡的活動,會遇到一些願意和你一起玩的玩伴,

Java用定義型作為HashMap的key

str boolean 順序 string 函數 出現 print 重新 對象 ??需要重寫hashCode()和equals()方法才可以實現自定義鍵在HashMap中的查找。 public class PhoneNumber { private int pre

轉:C#制作ORM映射學習筆記一 定義Attribute

技術 sage 其中 username pac ont 學習 collect reat 之前在做unity項目時發現只能用odbc連接數據庫,感覺非常的麻煩,因為之前做web開發的時候用慣了ORM映射,所以我想在unity中也用一下ORM(雖然我知道出於性能的考慮這樣做事不

c#(winform)中定義ListItem方便ComboBox添加Item項

urn left over string his 定義 return box item 1.定義ListItem類 public class ListItem { private string _key = string.Empty;

wordpress定義文章型描述信息description的使用

方法 類型 fun 應該 global scrip key var_dump script 上節教程中我們添加了一個自定義文章類型,配置使用了lablse參數,這裏繼續講解使用其它的參數。 先看description,這個參數是對新創建的文章類型的一個簡短描述,添加之後後臺

React實踐:定義html特性不顯示

clean 框架 user use scenarios () each 後來 方法 發現React中自定義的html特性在render後是不現實,而且getAttribute方法也只能獲取到undefined。 後來去stackoverflow提問,網友回答說: It de