==================
Loading DWG Models
==================

|HPSNOW| is able to load DWG models using the RealDWG integration. You must be a RealDWG licensee in order to use the interface. DWG is only available on Windows platforms. See the :doc:`release notes </general/release_notes/index>` for platform-specific information. DXF files are also supported.

The Sprockets DWG module is used to read DWG and DXF files through the Autodesk's RealDWG API. Once the file has been imported, the integration creates a component tree with support for a model browser. The user is then able to query the model either through the component structure, the |HPSNOW| scene graph, or directly through RealDWG. Data mapping is achieved through the ``HPS::DWG::Component`` class, which lets the user access the ``AcDbObjectId`` object associated with each component, which in turn can be used with the RealDWG API.


Prerequisites
=============

RealDWG is initialized after the ``HPS::World`` constructor has been called, at which point you can make function calls to RealDWG. RealDWG becomes uninitialized during the |HPSNOW| shutdown procedure. After the shutdown begins, you can no longer make calls to RealDWG.

The steps for loading DWG/DXF models are delineated below:


Step 1: Get RealDWG
-------------------

In order to use the RealDWG functionality, you must install the native RealDWG libraries. If you have licensed RealDWG through Tech Soft 3D, you may download the package from our `Developer Zone <http://developer.techsoft3d.com/toolkits/realdwg/>`_. The supported version of the RealDWG SDK is noted in the :doc:`release notes </general/release_notes/index>`. The RealDWG DLLs must be distributed with your application.
 

Step 2: Include RealDWG Header
------------------------------

To utilize the RealDWG importer, you need to include *sprk_dwg.h* in your source.


Step 3: Add RealDWG to Your PATH
--------------------------------

In order to use DWG, it's necessary to add the RealDWG directory to your machine's PATH. If you're using RealDWG Object Enablers (optional), then also 
make sure that the directory containing the DBX files for the Object Enablers is located in your PATH prior to initializing %HPS.


Import Example
==============

To import RealDWG files, |HPSNOW| uses the same basic framework as it does for other file types. The main difference is the use of functions from the ``HPS::DWG`` container class.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00770_realdwg_import.cpp
		   :start-after: //! [realdwg_import]
		   :end-before: //! [realdwg_import]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00770_realdwg_import.cs
		   :start-after: //! [realdwg_import]
		   :end-before: //! [realdwg_import]

The DWG import options can have a significant effect on the load time of certain models:

* ``SetMaxTessellationDeviation`` - This option specifies how finely to tessellate shells and meshes imported through DWG. Smaller numbers create more detailed and complex geometry.
* ``SetUnreferencedRecords`` - This option specifies whether to import parts of the drawings which are present, but not referenced in the model. Turning this off can result in a faster import.

If your model contains textures, and those textures are stored in an unusual location, you can specify the texture directory in the import options kit using ``SetTextureDirectories``.


.. _dwg_components:

DWG Components
==============

The Sprocket DWG module builds a component structure as it imports a DWG file. DWG components can be one of the following types:

#. ``DWGModelFile`` - The top of the hierarchy. Represents an ``AcDbDatabase`` object in RealDWG.
#. ``DWGBlockTable`` - The block table. This is always found directly under the ``DWGModelFile``. Represents an ``AcDbBlockTable`` object in RealDWG.
#. ``DWGLayerTable`` - The layer table. This is always found directly under the ``DWGModelFile``. Represents an ``AcDbLayerTable`` object in RealDWG.
#. ``DWGLayout`` - A DWG Layout. Found under the ``DWGBlockTable``. Represents an ``AcDbLayout`` object in RealDWG.
#. ``DWGBlockTableRecord`` - A record inside the Block Table. Found under the ``DWGBlockTable``. Represents an ``AcDbBlockTableRecord`` object in RealDWG.
#. ``DWGLayer`` - A layer. Found under the ``DWGLayerTable``. Represents an ``AcDbLayer`` object in RealDWG.
#. ``DWGEntity`` - A geometric entity. Found under a ``DWGLayout`` or a ``DWGBlockTableRecord``, or under another ``DWGEntity``. Represents an ``AcDbEntity`` object in RealDWG.
 
You can ask a component what type it is by calling the ``Component::GetComponentType`` function. All DWG components have the ``DWGComponentMask`` set on them. Therefore, you can tell if a component is a ``DWGComponent`` because ``Component::HasComponentType(ComponentType::DWGComponentMask)`` will return ``true``.


Working With Layers
-------------------

As an example of how to use the component type to operate on an object, we'll look at a code sample that deals with layers. Once you have identified that a component you are interested in is of type ``DWGLayer``, you can build a ``DWG::Layer`` object with it. With a layer object, you can enable and disable visibility, or return the visibility status. Below is an example of doing this:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00770_realdwg_import.cpp
		   :start-after: //! [realdwg_layers]
		   :end-before: //! [realdwg_layers]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00770_realdwg_import.cs
		   :start-after: //! [realdwg_layers]
		   :end-before: //! [realdwg_layers]
		   

.. _dwg_cadmodel:

The DWG CAD Model
=================

The ``HPS::DWG::CADModel`` class derives from ``HPS::CADModel``. In addition to the functions available in ``HPS::CADModel``, the ``HPS::DWG::CADModel`` class has access to these three extra functions:

* ``ActivateDefaultLayout`` - This function activates the default Layout. It is equivalent to calling ``ActivateDefaultCapture``.
* ``GetDWGDatabase`` - Returns the DWGDatabase pointer. The user can request the database to use it in RealDWG calls. The user should NEVER delete a database pointer it gets from this function.
* ``GetAllLayouts`` - Returns a list of layouts associated with this CAD model.

Here is an example of how to activate the default layout:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00770_realdwg_import.cpp
		   :start-after: //! [realdwg_activate_layout]
		   :end-before: //! [realdwg_activate_layout]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00770_realdwg_import.cs
		   :start-after: //! [realdwg_activate_layout]
		   :end-before: //! [realdwg_activate_layout]

Getting an array of all layouts from the CAD model may be done in the following way:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00770_realdwg_import.cpp
		   :start-after: //! [realdwg_get_all_layouts]
		   :end-before: //! [realdwg_get_all_layouts]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00770_realdwg_import.cs
		   :start-after: //! [realdwg_get_all_layouts]
		   :end-before: //! [realdwg_get_all_layouts]
		   
Here is an example of how to get a ``DWGObjectID`` from the layout object, and using it with RealDWG::

	// get the object id
	HPS::DWG::Layout layout = cad_model.GetAllLayouts()[0];
	DWGObjectID * object_id = layout.GetDWGObjectID();
	AcDbObjectId * acdb_object_id = reinterpret_cast<AcDbObjectId *>(object_id);
	 
	// open the object
	AcDbObject * object = nullptr;
	acdbOpenObject(object, *acdb_object_id, AcDb::kForRead);
	 
	// ...
	// do something with it
	// ...
	 
	// cleanup
	object->close();


Acquiring a Reference to the DWG Database
-----------------------------------------

This is an example of getting and using the DWG database from a CAD model object::

	//get the database pointer from the CAD Model
	DWGDatabase * database = cad_model.GetDWGDatabase();
	AcDbDatabase * acdb_database = reinterpret_cast<AcDbDatabase *>(database);
	  
	// Now you can use it to access RealDWG
	ACHAR * dimension_block;
	acdb_database->getDimblk(dimension_block);
	acdbFree(dimension_block);

**WARNING:** You should never try to delete a RealDWG database pointer!


Metadata
========

Metadata is additional non-geometric information that is associated with an ``HPS::DWG::Component``. Each piece of metadata is a name-value pair, and the values are always returned as ``HPS::StringMetadata``.

You can ask for the following metadata by calling ``GetMetadata`` from any ``HPS::DWG::Component``:

* "Name" - Either returns the name of the component, or if the component has no name returns a string formatted as follows: <RealDWG Entity Type> <RealDWG Handle>. Example: ``AcDbPolyline 1AB45``.
* "Handle" - Returns the hexadecimal handle of the entity associated with the component.
* "Layer" - Returns the name of the layer associated to this component, if any.
* "Units" - Returns the units used in the drawing. Only available from the DWG CAD Model.


Limitations
===========

Multiline Text
--------------

When multiline text is encountered, RealDWG explodes it into fragments. These fragments are not guaranteed to match those produced by AutoCAD. (Example: in a two line multi-line text, the last word of the first line might actually appear as the first word of the second line).

Line Patterns Containing Glyphs and Shapes
------------------------------------------

Line patterns containing glyphs and SHX shapes are not supported.
