Updates


October 25, 2014. Posted GeometricToolsEngine1p5.zip.
October 25, 2014. Added the ability to control _ITERATOR_DEBUG_LEVEL globally by defining values for this in GTEngineDEF.h. The global exposure required some header files to have includes of GTEngineDEF.h. In debug configurations, the maximum amount of iterator debugging is enabled in Microsoft Visual Studio. This can often lead to very long debug times, which might be painful during development. Turning it off can speed up the times, but of course you will not have the benefit of trapping iterator problems or range checking. Three files needed the GTE_IMPEXP flag added (DLL configurations have not yet been added, however). On Linux and Macintosh, the file needed an include of <cstring> for memset to be defined. Microsoft Visual Studio implicitly allows this function without the include.
October 24, 2014. Added code for triangulation of a simple polygon, a polygon with holes, or a tree of nested polygons. The code uses constrained Delaunay triangulation. The sample application shows how you can take advantage of the convex hull that the code generates, where the triangles are classified as inside the polygon or outside the polygon.
October 23, 2014. Ported the min-heap template class from Wild Magic. The class is intended to be a priority queue with the additional behavior that non-root heap nodes can have their weights modified followed by an update step that restores the heap to a min-heap. This is useful in several geometric algorithms. The comments in the header file provide more details and an example use in a geometric algorithm. These 2D sample applications were designed to illustrate computational geometry algorithms and draw the results in a fixed-side window. The lambda expressions used for drawing, however, require that the window not be resized because they access the screen texture whose size is determined by the initial window size. In the main function, we now set parameters.allowResize = false. Modified the Load functions to have a parameter that allows you to disable the pixel type check. This is useful when one application saves the file, another loads it, the pixel types are compatible, but the run-time type information does not match. Added an include command to ensure the file compiles if the pre-compiled header system is disabled.
October 20, 2014. The volume equation for a dodecahedron was in error.
October 19, 2014. Fixed the conversions from matrix or quaternion to axis-angle. The Wild Magic code had a wrapper Math<Real>::ACos(z) that tested for out-of-range z, clamping the input to [-1,1] by using if-then statements. This code was replaced by clamping using std::min and std::max, but was incorrectly implemented. Also, the implicit conversion from Rotation<N,Real> to Euler angles did not work because the caller needs to specify the order of axes. The implicit conversion was replaced by an operator() member that allows the user to specify the order. (Our internal unit tests were updated accordingly.)
October 18, 2014. Added two member functions that can be used to address some practical problems that arise when working with planar meshes. The extensive comments in the header file explain what the problems can be and how to deal with them.
October 16, 2014. Added a convenient GetComponents function that returns TriangleKey objects rather than pointers from the containers of the calling ETManifoldMesh object. This allows you to clear or destroy the mesh before consuming the components. Added tests for edges that have length zero and assigned reasonable weights. Such degeneracies can happen unexpectedly due to floating-point rounding errors; for example, you might start with a mesh with distinct vertices and run a smoothing filter that can lead to duplicate vertices.
October 15, 2014. The DoQuery function had a case where result.intersect was uninitialized on return. Restructured the code to be clearer about setting members of result and removed the Logger code. Revised the test code for both line-capsule and line-cylinder and moved it into the formal unit test suite.
October 14, 2014. Some code contained assignments of ETManifoldMesh objects, but the class does not have a copy constructor or assignment operator. The std::map members have dynamically allocated objects, so the assignments lead to memory leaks. Implemented a Clear() function, because the application code really wants to reset the mesh objects rather than copy them, but added a copy constructor and assignment operator in case other applications do require copies.
October 13, 2014. The segment-object and ray-object tests use the line-object test to produce a t-interval of intersection corresponding to the line. The t-interval is then intersected with the segment t-interval or ray t-interval to determine the final intersection. The interval-interval test results needed to be used in the final determination. This was a porting error from Wild Magic to GTEngine.
October 12, 2014. Ported the Wild Magic code for triangulation of polygons, nested polygons, and trees of nested polygons using ear clipping.
October 8, 2014. The SetEnvironment functions needed their search paths modified because of the merging of the old Numerics sample folder into Mathematics.
October 7, 2014. Removed some of the flag testing in the Initialize call because they do not occur for structured buffers. Added LogWarning statements to the TestIntersection calls when a bounding sphere radius is zero. The picking system requires the bounding spheres to be computed, but the user is responsible for calling UpdateModelBound on a Visual object before passing it to the picking system. The LogWarning, when it occurs, is a hint that perhaps you did not call the update function. The typecast of mCounterStaging in GetNumActiveElements is not necessary. In a previous version of the class, mCounterStaging was in a base class and declared as ID3D11Resource*, which at that time required the typecast. The CPU copy of the power factor is modified in the application code but on each change the engine needed to update the GPU copy.
October 6, 2014. Revised the design of the sample application to be more clear about the concepts it illustrates. The original design had a 512x256 application with the left subwindow showing the rendered square and the right subwindow showing the linearized depth of the rendering. The new design has a 512x512 window and allows you to select any of 7 overlays. See the sample application webpage for details and screen captures.
October 5, 2014. Added a query IsOriented() to determine whether the mesh is orientable (all triangles in a connected component have the same topological orientation). Added a query GetComponents(...) to compute the connected components of the edge-triangle graph of the mesh. Added a smaller helper class to generate a set of unique vertices from a triangle soup or from a collection of indexed triangles. The file did not compile when GTE_IMAGICS_ASSERT_ON_INVALID_INDEX was exposed. Changed an index i to d. Moved the code contain this preprocessor symbol to the inline file so that our test framework will trap such problems. Made similar changes to test GTE_VERIFY_PRIMITIVE_TYPE in the IndexBuffer class. The inline file is new.
October 2, 2014. Added a new sample that illustrates shaders that combine texturing and per-pixel directional lighting.
September 28, 2014. The engine was designed to allow you to run versions of DirectX 10 and previous. However, the default target strings to the ShaderFactory::Create* compilation functions were hard-coded to use Shader Model 5 (DirectX 11). A static member was added, std::string ShaderFactory::defaultShaderModel, whose default is "5_0". If you want to use DirectX 10.0 in any of our samples, you must add two lines of code in the main function. For example, in the sample file GTEngine/Basics/VertexColoring/VertexColoring.cpp there is a block of code that sets members of parameters. Add two more lines,
    parameters.featureLevel = D3D_FEATURE_LEVEL_10_0;
    ShaderFactory::defaultShaderModel = "4_0";
DirectX 10.0 corresponds to Shader Model 4.0. If instead you want to run the sample with DirectX 10.1, then use
    parameters.featureLevel = D3D_FEATURE_LEVEL_10_1;
    ShaderFactory::defaultShaderModel = "4_1";
You may select a default shader model that is less powerful than what the feature level supports. For example, you can select feature level 11.0 yet have a default shader model of "4_1" for compiling the shaders. The sample file for blended terrain had hard-coded targets provided explicitly in the calls to the shader factory; these were replaced by strings using defaultShaderModel. During drag-resize of the window boundary, Window::OnResize needed to trigger a redraw. Added a call to Window::OnIdle to allow the application to redraw.
September 27, 2014. Removed the include of atlcomcli.h and added a simple wrapper for the COM objects. This eliminates the dependency of GTEngine on Microsoft's Active Template Library (ATL) so that the engine compiles using Microsoft Visual Studio 2013 Express Edition (which does not ship with MFC or ATL).
September 25, 2014. Posted GeometricToolsEngine1p4.zip.
September 25, 2014. Added a new class ComputeModel that allows you to pass information to algorithm implementations whether to use the GPU, multiple threads on the CPU, or single threading on the CPU. Derived classes can provide additional behavior such as callbacks to report progress of an algorithm. The number of bytes for an image was stored as a 32-bit integer. This is a limitation for 64-bit processors that can allocate more than 2GB of memory. Modified several members to be size_t, which is a 32-bit unsigned integer on a 32-bit processor or a 64-bit unsigned integer on a 64-bit processor. Any functions that use int for 1-dimensional indices were modified to use size_t.
September 24, 2014. Added an explicit namespace scope on ShaderFactory in the GTE_MAKE_HLSL_STRING macro so that the macro can be used outside a using namespace gte block.
September 22, 2014. An include of iostream was needed to access std::cout. Modified the functions to return the number of actual iterations used during bisection rather than just a Boolean result.
September 20, 2014. The member mNumBytes was set twice in the else-clause in the constructor.
September 19, 2014. Ported the Wild Magic physics sample named Cloth, which illustrates 2-dimensional mass-spring systems. Added a class for representing rectangle surfaces with specified surface but used for sampling to build triangle meshes. Wild Magic had such a class, but it was tied to the graphics system. The GTEngine class is independent of the graphics system. The linear system solver used successive replacement rather than simultaneous replacement. Switched to simultaneous replacement, using ping-pong buffers, to allow for simple multithreading. The class now accepts a parameter that specifies how many threads are dedicated to the linear system solver. Added an include of <string> so that the file would compile by itself as the only include in a cpp file.
September 18, 2014. Added a base class ParametricSurface for several of the surface classes. Added a class for computing the Darboux frame for a parametric surface. These are effectively a port of the Wild Magic class ParametricSurface. The uv-coordinate generation is slow when the number of vertices is very large. The bottleneck was the iteration over the std::map objects that store the adjacent vertex information. The sparse linear system solver now creates a data structure that stores the relevant information in an array and performs much better. The implementation of slerp had one more term in its arrays than what the theory specifies in D. Eberly, A fast and accurate algorithm for computing SLERP, The Journal of Graphics, GPU, and Game Tools, vol. 15, no. 3, pp. 161-176, October 21, 2011.
September 17, 2014. Fixed an error in the comments about which knots are equispaced for an open uniform curve.
September 16, 2014. Ported the Wild Magic physics sample named Rope, which illustrates 1-dimensional mass-spring systems. Added classes for computing the Frenet frame for a parametric curve. Added a class for representing tube surfaces with specified medial curve and radial function. Wild Magic had such a class, but it was tied to the graphics system. The GTEngine class is independent of the graphics system.
September 15, 2014. Added a base class ParametricCurve for the various curve classes. This is effectively a port and consolidation of the Wild Magic Curve{2,3}, SingleCurve{2,3}, and MultipleCurve{2,3} classes. Added set/get accessors for individual control points and weights for the B-spline and NURBS curve classes. Unit tests have been written for the base class and the derived classes.
September 14, 2014. The #Samples and #Tools folder names starting are not friendly to Linux because of the leading hash mark. The folders were moved to the corresponding folders without the hash marks. The #Data subfolder of Samples was also renamed (to Data), which required changing the path handling in several sample applications. Also, the Samples/Numerics applications were moved to the Samples/Mathematics folder because there is really no important distinction between the two types (just as in Wild Magic). Ported several Wild Magic physics library files to GTEngine. Changed the second public to private. This is a cosmetic change with no difference in the behavior of the application. In the constructor for CpuMassSpringVolume, reordered the initialization list according to C++ standards (initialization order is member order).
September 13, 2014. Posted GeometricToolsEngine1p3.zip.
September 13, 2014. A new sample application that demonstrates using the class GenerateMeshUV to automatically generate texture coordinates for a mesh that has rectangle or disk topology. The sample also illustrates resampling using the class PlanarMesh.
September 11, 2014. Ported the Wild Magic B-spline curve and surface code for least-squares fitting of data, including the sample applications. The mKeys member of the class was a std::vector type and is used heavily in the range-iteration-based for-loop in GetIndex. Because of the checked iterators used in that loop, the performance in debug builds was horrific. Changed the type of mKeys to a native array to improve the performance for debugging. In order to re-use a MeshFactory object with a different vertex format, the array that keeps track of whether texture coordinate channels occur had to be cleared when creating the vertex buffer. Added a new class that generates texture coordinates automatically for a mesh with rectangle or disk topology. The algorithm is based on barycentric mapping, mean-value weights, and Gauss-Seidel iteration for large sparse linear systems. Added a new class that manages a planar mesh and allows fast and exact point-in-triangle queries and computation of barycentric coordinates. This was added to support resampling of meshes with automatically generated texture coordinates. Fixed a comment that was cut-and-paste from another similar file.
September 3, 2014. Changed the LogError messages to LogInformation when an insertion will violate the manifold mesh requirement. Some applications might find it useful to attempt an insertion, using the returned null pointer as an indication to take an alternative action. You can set your Logger listeners to ignore LogInformation messages (or just ignore ones that are sent to MessageBox or OutputWindow); however, we also added the ability to turn off the LogInformation message specifically for these classes via a class member function. Added class member function to get 1-dimensional indices or tuples for various neighborhood configurations of a pixel. Modified the image processing utilities to use these member functions. Added a static assertion to the image classes that requires the PixelType to be trivially copyable, a requirement of the design of the Image classes. Removed the PixelRGBA8 and PixelBGRA8 classes because the engine does not use them (nor are they that useful). Removed the GteStandardImages.cpp file that explicitly instantiated image classes. The engine design has been not to force explicit instantiation of template classes. The mass-spring system class used Image3<Vector3<float>>, but the template type is not trivially copyable. The code was easily modified to use std::vector<Vector3<float>>.
August 31, 2014. Added support for picking point primitives and line segment primitives. The picking for triangles uses intersection tests. The picking for points and segments uses distance tests. The sample application was updated to show how this works. The line-segment distance code had a porting bug that was fixed; the returned distance was incorrectly set to zero when the segment closest point was an interior point. Modified our header dependency tool to trap problems when precompiled headers are disabled. The include of GTEngine.h in GTEnginePCH.h needed to be disabled to trap problems in cpp files. The following files had missing dependencies when we did this. These are nonessential changes for the engine, because the GTEngine project has precompiled headers enabled. You can get these changes when we post GTEngine 1.3.
August 30, 2014. Added the ability to specify the matrix storage convention and matrix-vector multiplication convention externally. The comments in the file explain the rationale and consequences of doing so. Added new template functions to allow conversions between N-tuples and (N+1)-tuples. These include HLift, HProject, Lift, and Project. The comments in the .h file explain what each function does. The HLift and HProject functions are particularly useful for conversions between Vector3<Real> and Vector4<Real> objects. The SetSegment and GetSegment functions needed to distinguish between disjoint line segments (IP_POLYSEGMENT_DISJOINT) and contiguous line segments (IP_POLYSEGMENT_CONTIGUOUS).
August 29, 2014. Posted GeometricToolsEngine1p2.zip.
August 29, 2014. Added HasMember functions to test for the existence of member data with the specified name. A small amount of refactoring of Picker to prepare for supporting point and line primitives (distance based). The triangle picking code was tested using a new sample application. Fixed a bug in the Shader constructor when generating the member layouts for constant buffers and texture buffers. The indices into the layout arrays were not incremented, which led to incorrect behavior for shaders with two or more such buffers. Fixed a bug in the GenerateLayout member function. The shader type's offset was used to determine member offset in the structure, but the shader variable's offset has to be used instead (at the root of the recursion). A change in the semantics for Environment::GetPath when no directories exist was not propagated to the append-consume buffer sample application, causing a bogus assertion when trying to find the HLSL file associated with the application. The hiding of the trackball rotation matrix inside the Window class prevented picking from working properly. The registration system that updated shader constants with projection-view-world transforms from the world transforms of associated objects needed a redesign. The trackball rotation is no longer applied implicitly. You can access it via a public member function. The Register/Unregister calls were replaced by two subscription interfaces, one to subscribe to changes in the camera changes and have the pvw-matrices automatically updated--this is what the Register/Unregister system did. However, there is interaction between updating world transforms and pvw-matrices for effects, so a second subscription interface is used to have world transforms of objects automatically updated when the virtual trackball moves. The redesign led to many changes in sample applications. While we were in there, we cleaned up and refactored some of the samples to make the code more readable (consistent use of 'bool SetEnvironment' and 'bool CreateScene'). The Window class also has a new member function for computing a picking line for the current viewport and camera settings. This is used in conjunction with the Picker class.
August 26, 2014. Refactored the basic lighting effects to share code, fixing several bugs in the process. Two new classes were added, LightingConstants and LightingEffect. Added a new sample application to illustrate the effects; this is a port of the Wild Magic 5 Lights sample. The files GteLightAmbientEffect.inl, GteLightDirectionPerVertexEffect.inl, GteLightDirectionPerPixelEffect.inl, GteLightPointPerVertexEffect.inl, GteLightPointPerPixelEffect.inl, GteLightSpotPerVertexEffect.inl, and GteLightSpotPerPixelEffect.inl were removed from the distribution. The MSDN documentation for ID3D11DeviceContext::IASetVertexBuffers and ID3D11DeviceContext::Draw(numVertices, startVertex) appears not to mention that startVertex is relative to the offsets[] passed to IASetVertexBuffers. Fixed the enabling of vertex buffers to set the offsets to zero. The DX11Engine::DrawPrimitive function passes the vertex buffer offset through the startVertex parameter.
August 19, 2014. Posted GeometricToolsEngine1p1.zip.
August 19, 2014. These modifications are related to getting the code, not including the Windows-specific graphics and application code, to compile on Linux and Macintosh OS X. The first batch of changes were consequences of trying to compile on Macintosh OS X. The second batch is due to Linux compilation, although changes in the first batch no doubt were needed anyway on Linux.

Hide the Windows-specific information from the other platforms. The compiler did not like the #pragma once in the precompiled header file. The LLVM compiler successfully compiled Delaunay2Mesh and Delaunay3Mesh in our header verification tool when you compile in a single file. However, when a build-project is initiated, LLVM attempted to use the template parameter Rational as if it were an actual type and complained when trying to instantiate Vector{2,3}::ComputeBarycentrics. In particular, we had a line if (std::abs(det) > epsilon) for which LLVM said std::abs is ambiguous and that it did not match any of the standard functions for floating-point types. For now, we modified the code for ComputeBarycentrics to use if (det < -epsilon || det > epsilon). LLVM does not have versions of the secure memcpy_s that Microsoft Visual Studio does. Added conditional compilation to handle this. Eliminated the typedef of Function. LLVM had difficulties with this in the derived classes. Removed the (WM5) using statements and added the explicit scoping by this->. Removed the explicit last parameter to ComputeBarycentrics. The default parameter has the same value. The file <iterator> needed to be included to access the definitions of std::begin, std::end, and std::reverse_iterator. Microsoft Visual Studio 2013 allowed the compilation without it, but not LLVM. The class had two member functions that required two implicit conversions to return values. One of them has to be explicit, and LLVM requires this. The definition of size_t appears to be built into Microsoft Visual Studio 2013. On LLVM, it is defined in <cstddef>, so this header file needed to be #include-d. The declaration for triangle barycentric coordinates was the incorrect size. The header needed to #include <set> because the class has a member using this container. We have an internal tool that #include-s each header file in a cpp file and tests whether it compiles. This is designed to expose a header file that might not #include any dependencies it has. If the header is for template classes or functions, we also explicitly instantiate those in order to trap any compiler errors. Naturally, the tool has precompiled headers disabled. Surprisingly, some code passed the tests when compiling with Microsoft Visual Studio 2013 but the same code failed compilation on LLVM. For example, the GetContainer function in GteContEllipsoid3.inl incorrectly had a Vector2 input when it should have been Vector3. This code passed the explicit instantiation compiler test using Microsoft Visual Studio 2013. Microsoft's compilers still violate the ANSI C++ standard that requires template derived classes to explicitly scope any access to template base class members or functions via this->mBaseMember and this->BaseFunction. [In Wild Magic, we chose the using statement in the derived-class headers but decided against this in GTEngine because of the potential change in access rights (public, protected, private).] Added typename modifiers to some variable declarations. Microsoft Visual Studio 2013 allowed the declarations without the modifiers, but not LLVM. BSNumber had a declaration to make BSRational a friend. Microsoft Visual Studio 2013 allowed the original code, but not LLVM. Forward declared the BSRational template and modified the friend statement. [The same mechanism had been used in Wild Magic to satisfy all compilers.] Microsoft Visual Studio 2013 allows you to make calls to math library functions such as std::abs and sqrt without #include-ing <cmath>. Added the #include to satisfy LLVM. Removed an incorrect static cast of a 32-bit value to a 64-bit value when the return value of the function is in fact 32-bit. The explicit instantiation of the oppositeFace array required a template< > modifier. The explicit instantiation of image classes needed to be inside a namespace block. Removed the AlignedMemory class from the engine. It is not used, and the _aligned_malloc and _aligned_free calls do not exist on Macintosh OS X. The changes below were necessary after the previous ones to get the code to compile on Linux.

The explicit instantiations had to occur inside a namespace block. A 'using namespace gte' was not sufficient. The class uses the var-args system so we needed to include <cstdarg>. The files use std::numeric_limits and needed to include <limits>. The files use memcpy or memset and needed to include <cstring>. The conditional compilation is now based on WIN32 (or not). The files use std::min, std::max, std::sort, or std::nth_element and needed to include <algorithm>.
August 17, 2014. These modifications are related to the porting of the Wild Magic interpolation code to GTEngine.

Ported most of the Wild Magic interpolation code to GTEngine. A sample application illustrates use of the interpolators for 2D height-field data. Added wrappers for the meshes produced by Delaunay triangulation and tetrahedralization. Access to the input vertices of the DelaunayN classes was required to support this. The wrappers allow the interpolators to interact with general triangles mesh that are not produced by the Delaunay code. (Wild Magic forced you to use Delaunay meshes.) Added a mesh creator for regular triangle meshes ("half" a rectangle mesh). When computing barycentric coordinates, replaced the separate Dot and Cross functions by the single calls to DotCross. Added functions AllocateMapN and DeallocateMapN for N = 2, 3, 4. This allows for wrapping an already existing 1-dimensional array with multidimensional array access.
August 15, 2014. Fixed a typographical error in Equation (14). (Thanks to Pierre Maxted for reporting this.) Replaced the LaTeX verbatim commands with lstlisting commands for more readable pseudocode.
August 13, 2014. The files were missing the #pragma once guards against multiple inclusions.
August 11, 2014. Posted GeometricToolsEngine1p0.zip.