Vectorization and Visualization in Drawings

  1. FAQ

Is there any upper limit to number of entities or points which can be exported to a .dgn model?

dgn multivertex elements has vertex limit: documentation says, the limit is 5000, but real limit is 5456.

You can split too long line strings on your dgn import code. And I recommend you to use limit == 5000.

How to get entity from view or database by mouse click point?

OdaMfcApp use OdDbSelectionSet::select method for selection. You can use kPoint selection mode to select single entity by click or kCrossing for selection of multiple entities.

How to get geometry from overall viewport?

Overall viewport is a special case. It has no geometry. It specifies parameters of Layout view (view center, zoom level etc.) for Paper Space entities. Unlike other viewports it does not display entities from Model Space.

Can I create and use multiple OdGsView in OdGsDevice object?

OdDbGsManager::setupActiveLayoutViews() can conflict with views which is already added in device. You can add more views after OdDbGsManager::setupActiveLayoutViews() call.

I'm having issues in loading time before anything can be visualized in the view within my MFC C++ application. I've noticed a .DWG file (with significant number of text) will take over 40 seconds to show up in my own viewer (the same with ODA Viewer).

Currently we have option 'Use TTF font cache' which allow to speed up the vectorization process.

Talking about the rendering performance - some speed up can be reached if it is possible to put as much text as it possible to the one entity.

Also our OdTvGsDevice have option "EnableMultithread", which in your case will significanly speed up the vectorization process (it is different option in comparison with the similar option for the DWG to VSF import).

How to determine the drawing order using OdVectorizer? When Dumper in vectorizer prints out the data how do we know which should be drawn on bottom and which on top?

Drawing order is used in .dwg only for 2dWireframe visual style. SortEnts Table is used during block drawing and user gets geometry in OdVectorizeEx in this order.

All other modes (styles) are considered 3D, so the geometry will be vectorized in the order in which it is in the block, SortEnts will not be applied. In 3D the drawing order is not important, because the depth buffer is used, the geometry is drawn in 3D space.

What if the difference between OdDbBlockTableRecord::getGeomExtents() and zoomExtents() in view?

OdDbBlockTableRecord::getGeomExtents() does not take into account layers visibility. Layers can be frozen in viewports and extents can be different in different viewports.

See AbstractViewPE.h

This protocol extension can be applied to OdDbViewport, OdDbViewportTableRecord, OdDbViewTableRecord.

See sample code in Kernel/Examples/Exports/RasterExport

How to implement orbiting around a custom point? The intersection of the viewing ray determined by the mouse click location and the object surface is my desired center point. I tried using the entities inersectWith function, but got eNotImplementedYet.

You can implement entity intersection using generic way - though entity vectorization and intersecting accumulated triangles. Look for ExEntityIntersection project - this is entities intersection module for .dwg database. Since this is example - it is implement only part of functionality for simple entities. But actually intersections can be solved for any kind of graphics using vectorization - this solution was used in ExDgnElementIntersect project for .dgn database. You can simply adopt exist solution for .dgn database into ExEntityIntersection for .dwg database. Alternatively you can invoke vectorizer onto your side and process entities intersection without usage of OdDbEntity::inersectWith() methods.

How to extract spline in a .dwg file and draw it using lines? Is there a way to do it other that vectorize?

Check virtual OdResult OdDbCurve::getOdGeCurve ( OdGeCurve3d*& pGeCurve, const OdGeTol& tol = OdGeContext::gTol ) const;
use pGeCurve->getSamplePoints(...) and delete OdDbCurve;

Is there any way to render a custom object?

A custom entity can be rendered if you implement its worldDraw() method (and viewportDraw() optionally).

How to know the order of rendering entities (in 2D wireframe and 3D render modes) ?

It works differently in 2D wireframe and 3D render modes.

In 3D modes, the rendering order depends on the position of the two entities (which one is closer to the camera). If the entities are in the same plane, the result is unpredictable. In 2D wireframe, the render mode depends on the drawing order. By default, the entity that appears first in the file is rendered first.

But this order can be changed using OdDbSortentsTable methods.

The sort table is returned by the OdDbBlockTableRecord::getSortentsTable() method (it makes sense for layout blocks).

How can I use ODA SDKs for rendering drawings on a web page?

As an example, look at ODA Online File Converter, which is a Oracle® Java® application that converts a .dwg file to a .pdf file and displays a preview on a web page. The source files of the converter are available for downloading at the same location.

Is there a way to dynamically render objects created on the existing view using a different render mode?

There is no direct way to render entities inside a single view using different render modes. To emulate this behavior, you can create additional overlapping views with a different render mode and dynamically draw created objects using it:

  1. Create the intermediate view (pView->device()->createView).
  2. Append the view into the device on the top of all other views (device()->addView(pNewView)).
  3. Copy all view parameters into the new view (pNewView->viewParameters(pView)).
  4. Add your drawables into the new view (pNewView->add(pSelectionRectDrawable)).
  5. Now you can change the view parameters (such as pView->setMode(OdGsView::k2dOptimized)).
  6. device()->update() // draw
  7. Now you can remove the new view from the device until the next update (device()->eraseView(pNewView)).

After loading a 1-bit palette .png file into an OdGiRasterImage object and attempting to render it using rasterImageDc(), the rendered output does not show the image.

ODA SDK reads and vectorizes monochrome images (.bmp, .tiff, .png) without using the palette colors stored inside the image. A dark color inside the palette is substituted with a background drawing color (or by a secondary color set in OdGiSubEntityTraits, or is transparent if image transparency is enabled). A light color inside the palette is substituted with the color specified in OdGiSubEntityTraits during the vectorization. So you don't see your image because it is completely filled with the background color, but you can see that it is rendered if the image overlaps other geometry.

This behavior is the same as in Autodesk® AutoCAD® for monochrome images in .bmp and .tiff formats, but .png images are handled as non-monochrome rasters.

How to cancel vectorization?

OdGiContext and its inheritor OdGiBaseVectorizer have the regenAbort() function. It can be overridden to return true and stop vectorization.

Is there a fixed order of entity vectorization in a drawing? Is it modifiable?

The order of vectorization can be set by a SortEnts table (a DbSortentsTable object) attached to the BlockTableRecord. If there is no SortEnts table, entities usually come in the order of their creation. Results may be different for different renderers. For example, in 3D mode (device supports Z-buffer) an entity that is closer to you is on the top of other entities.

Why does every vectorized object become wireframe?

Probably your drawings with polyface meshes is stored in Wireframe or 2dWireframe render mode. Shell primitives will be filled by default only for HiddenLine or Shaded render modes.