Skip to search.

Breaking News Visit Yahoo! News for the latest.

×Close this window

vtp · The Virtual Terrain Project

The Yahoo! Groups Product Blog

Check it out!

Group Information

  • Members: 537
  • Category: Graphics
  • Founded: Aug 21, 2000
  • Language: English
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Message search is now enhanced, find messages faster. Take it for a spin.

Messages

Advanced
Messages Help
Messages 5273 - 5302 of 6247   Oldest  |  < Older  |  Newer >  |  Newest
Messages: Show Message Summaries Sort by Date ^  
#5273 From: "Bryan Berg" <bberg@...>
Date: Tue Mar 4, 2008 10:27 pm
Subject: running wxenviro from a dll
bberg@...
Send Email Send Email
 
Hi all,



So I would like to be able to run part of wx enviro through a dll.



All I really need is the part of the screen which shows the terrain.



Is this feasible?



Any suggestions (on where to start .)?



Thanks!



Bryan







[Non-text portions of this message have been removed]

#5274 From: "Ben Discoe" <list1@...>
Date: Tue Mar 4, 2008 10:36 pm
Subject: RE: running wxenviro from a dll
bdiscoe
Send Email Send Email
 
Bryan,

Vtocx (http://vterrain.org/Doc/vtocx.html) shows how to use vtlib as an ActiveX
control, which is a kind of DLL.

In fact it would be even simpler to make a plain Win32 DLL, without all the
MFC/OCX stuff - depending on what application you want the DLL to plug into. 
Just take any of the vtlib Simple example applications, remove the application
part (e.g. main()), and build it as a DLL.

-Ben

> -----Original Message-----
> From: vtp@yahoogroups.com [mailto:vtp@yahoogroups.com] On Behalf Of Bryan
> Berg
> Sent: Tuesday, March 04, 2008 12:28 PM
> To: vtp@yahoogroups.com
> Subject: [vtp] running wxenviro from a dll
>
> Hi all,
> So I would like to be able to run part of wx enviro through a dll.
> All I really need is the part of the screen which shows the terrain.
> Is this feasible?
> Any suggestions (on where to start .)?
> Thanks!
> Bryan

#5275 From: "Bryan Berg" <bberg@...>
Date: Tue Mar 4, 2008 10:51 pm
Subject: RE: running wxenviro from a dll
bberg@...
Send Email Send Email
 
Would that work for the wxenviro app ?



And if so, do I just need to right click on the project and go to .



Configuration properties --> General --> Configuration Type



And change from application(.exe) to dll ?



Thanks!



Bryan



[Non-text portions of this message have been removed]

#5276 From: "Ben Discoe" <list1@...>
Date: Tue Mar 4, 2008 11:03 pm
Subject: RE: running wxenviro from a dll
bdiscoe
Send Email Send Email
 
> From: Bryan Berg
> Sent: Tuesday, March 04, 2008 12:52 PM
>
> Would that work for the wxenviro app ?

You wrote you "only need the part of the screen which shows the terrain". 
Hence, you don't need all the other stuff that Enviro provides - the menus,
toolbars, and dialogs.  Hence, there is no need to pare down Enviro to be a DLL.
Just use any of the Simple example apps - which render a terrain.

> And if so, do I just need to right click on the project and go to .
> Configuration properties --> General --> Configuration Type
> And change from application(.exe) to dll ?

Basically, yes.  You don't need wx,mfc,glut or any other app framework.  So
remove that part.  Just use the code that calls vtlib to create and render a
terrain, and build that as a DLL.

-Ben

#5277 From: "Bryan Berg" <bberg@...>
Date: Tue Mar 4, 2008 11:22 pm
Subject: RE: running wxenviro from a dll
bberg@...
Send Email Send Email
 
Right . but we do need the paging tile set component of enviro.



Can one of the other simple apps do that - if say vtbuilder has already been
run to create the tile sets ?



If so which one?



Thanks!!!



Bryan



[Non-text portions of this message have been removed]

#5278 From: "Bryan Berg" <bberg@...>
Date: Tue Mar 4, 2008 11:28 pm
Subject: RE: running wxenviro from a dll
bberg@...
Send Email Send Email
 
Oh, and Ben check your email for some pertinent time sensitive links.



Bryan



[Non-text portions of this message have been removed]

#5279 From: "Bryan Berg" <bberg@...>
Date: Thu Mar 6, 2008 1:43 am
Subject: building wx from scratch
bberg@...
Send Email Send Email
 
Hi,



So I'm trying to build the wx_dll from scratch to step through the code.



I originally built it using the wx.sln file (as suggested from the wxwidgets
website), but than to integrate it with vtp I followed vtp's instructions
for building with dll-unicode.



Perhaps I've lost a lib to link.  For building the aui lib, I have:



winmm.lib

comctl32.lib

rpcrt4.lib

wsock32.lib

odbc32.lib

..\..\lib\vc_dll\wxbase28ud.lib



I removed



..\..\lib\vc_dll\wxmsw28ud_adv.lib

..\..\lib\vc_dll\wxmsw28ud_core.lib



Because I don't have those libraries.  Maybe I should ?



Thanks !



Bryan







[Non-text portions of this message have been removed]

#5280 From: "Bryan Berg" <bberg@...>
Date: Fri Mar 7, 2008 1:06 am
Subject: building wx from scratch ... continued
bberg@...
Send Email Send Email
 
Hi,



So I rebuilt wxwidgets from scratch using all of the modes specified, but
now when I try building wxsimple I get an error that it cannot find
wxbase28ud_odbc.lib



Any ideas ?



Thanks !



Bryan



[Non-text portions of this message have been removed]

#5281 From: Sam Kramer <samkramer_2000@...>
Date: Fri Mar 7, 2008 2:53 pm
Subject: Re: building wx from scratch ... continued
samkramer_2000
Send Email Send Email
 
Bryan,

When building the libraries, make sure that the settings are consistent for each
of the projects. Specifically, keep in mind that there are four kinds of builds:
debug, unicode debug, release, and unicode release.

The library you specified below, wxbase28ud_odbc.lib, is a unicode debug build.

--Sam

----- Original Message ----
From: Bryan Berg <bberg@...>
To: vtp@yahoogroups.com
Sent: Thursday, March 6, 2008 8:06:37 PM
Subject: [vtp] building wx from scratch ... continued

Hi,

So I rebuilt wxwidgets from scratch using all of the modes specified, but
now when I try building wxsimple I get an error that it cannot find
wxbase28ud_odbc. lib

Any ideas ?

Thanks !

Bryan

[Non-text portions of this message have been removed]





      
________________________________________________________________________________\
____
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. 
http://tools.search.yahoo.com/newsearch/category.php?category=shopping

[Non-text portions of this message have been removed]

#5282 From: "Bryan Berg" <bberg@...>
Date: Sat Mar 8, 2008 12:25 am
Subject: building wx_dll from scratch ... continued
bberg@...
Send Email Send Email
 
Okay so I finally got wxSimple to build . hip hip ...



I did not have any luck using the setup.h files provided on vterrain

  (maybe if I tried them at the end they would work).



I used the ones that came with the wxwidgets download and changed:

(in the directory)

C:\wxWidgets-2.8.7\include\wx\msw



#define wxUSE_GLCANVAS       1

#define wxUSE_ODBC          1



Hope this helps!



Bryan



[Non-text portions of this message have been removed]

#5283 From: "Ben Discoe" <ben@...>
Date: Tue Mar 11, 2008 9:38 am
Subject: international filename support
bdiscoe
Send Email Send Email
 
I have added an item to the FAQ, http://vterrain.org/Site/faq.html#T9

Q: On Windows, some files cannot be opened, if the path name contains
international characters, like "F:\数据\file.tif"

A: This is a limitation of some the component libraries inside the VTP
(primarily, GDAL and OSG) which do not accept Unicode (or UTF-8) filenames.  The
VTP software itself completely supports Unicode and internationalization.  The
component libraries have been notified of the problem and solution, but to date
they have not been fixed.

-Ben

-----Original Message-----
From: qljs qljs [mailto:cdw1984518@...]
Sent: Monday, March 10, 2008 6:06 PM
To: Ben Discoe

Hi Ben,

[...] I suggest you add the problem below to
FAQ so the others might not make the same mistake:

GDAL can not read data if they're on a directory that contains Chinese
characters. a lot of weird error happens:
cann't open tiff when it is in "F:\数据\"
cann't expand archieves if the the archive file  is in "F:\数据\"。

What is the problem and how to modify it ?

#5284 From: "Ben Discoe" <ben@...>
Date: Wed Mar 12, 2008 9:43 am
Subject: RE: VTP Application Debug version cann't run and cannot get through with the tutorial
bdiscoe
Send Email Send Email
 
Qljs,

Do i correctly understand your problem:

1. In the Release build, the program runs correctly.
2. In the Debug build, running inside the debugger, it does not run correctly?

If that is correct, then it is indeed a problem others have found
At the first, i recommend to use Release when running the tutorials. :)

Replacing the debug with release dependencies (like gdal14d with gdal14) is not
a good idea.  The debug version of the library is not 100% compatible with the
release version.  If the app was built in debug, it should use the debug
dependencies.

There are some very complex and difficult to track MSVC problems, with debug
dependencies and manifests and the debugger.  Basically, if the library was
built with one version of the debug standard library manifest, and the
application with another version, then the debugger refuses to work correctly -
even if those version are supposedly compatible.  That is probably the problem
you are seeing.  It is a problem with VC8 (2005).  There was no problem with VC7
(2003), it was so much easier back then. :(  Really, it is so horrible that i
really wish i could flee this platform.  But there is no IDE on Linux that comes
anywhere close in power, so here we are suffering through Microsoft nightmares..

Some things you could try (beside just running Release):
1. Build your own GDAL and wx binaries, with your exact version of the compiler.
(a lot of work..)
2. Make sure your VC8 SP1 is installed (hopefully, the identical standard
libraries as my machine here, on which i built the GDAL and wx binaries for
you.)

Good luck,
Ben

> -----Original Message-----
> From: qljs qljs [mailto:cdw1984518@...]
> Sent: Tuesday, March 11, 2008 10:31 PM
> To: Ben Discoe
> Subject: Re: VTP Application Debug version cann't run and cannot get
> through with the tutorial
>
> Hi Ben,
>
> Is there anything wrong with the discuss group at yahoo? I tried to
> join it but couldn't open the page groups.yahoo.com. If you have the
> privilege to add my email to the group, please add me.
>
> I have intalled vs2005 and the patch vcredist_x86.exe. After compiling
> the source code successfully, I found that only the Release Unicode
> version can run. The Debug Unicode version cannot run, saying:
>
> **********************************************************
> "VTBuilder.exe":
> ...
> "VTBuilder.exe": 已加载"E:\vterrain\APIs\gdal142-vc8\bin\gdal14d-
> vc8.dll",未加载任何符号。
> LDR: LdrpWalkImportDescriptor() failed to probe
> E:\vterrain\APIs\gdal142-vc8\bin\gdal14d-vc8.dll for its manifest,
> ntstatus 0xc0150002
> 调试器:: 在进程加载过程中引发了未处理的无法继续的异常
> 程序"[1784] VTBuilder.exe: 本机"已退出,返回值为 -1072365566
(0xc0150002)。
> ***************************
>
> I thought that you might not understand Chinese,^-^. Anyway, the main
> problem is in this setence"LDR: LdrpWalkImportDescriptor() failed to
> probe E:\vterrain\APIs\gdal142-vc8\bin\gdal14d-vc8.dll for its
> manifest, ntstatus 0xc0150002"
>
> In the "property page" of project VTBuilder, I changed the link
> library from gdal14d-vc8.dll to gdal14-vc8.dll. The program went
> further but finally failed to start. The message was:
>
> **
> LDR: LdrpWalkImportDescriptor() failed to probe
> E:\vterrain\APIs\wx2.8.7\lib\vc_dll\wxbase28ud_vc_custom.dll for its
> manifest, ntstatus 0xc0150002
> ****
>
> I thought that the if I changed wxbase28ud.lib to wxbase28u.lib
> somewhere in the link library, the problem might be solved. However,
> this time I cannot found it in the property page. Can you help me to
> solve it?
>
> Thanks a lot.

#5285 From: "emagnet.geo" <eric.dennison@...>
Date: Wed Mar 12, 2008 10:00 am
Subject: VTP build problem
emagnet.geo
Send Email Send Email
 
I am attempting to build VTP in Ubuntu Linux. Worked through a
seemingly endless series of dependency issues until I got to
glutSimple. Does anyone know how to resolve this?

TIA -Eric


make[2]: Entering directory `/home/ericd/work/VTP/TerrainApps/glutSimple'
g++ -o glutSimple -L/usr/local/lib
-L/home/ericd/work/VTP/TerrainSDK/vtdata
-L/home/ericd/work/VTP/TerrainSDK/xmlhelper
-L/home/ericd/work/VTP/TerrainSDK/unzip
-L/home/ericd/work/VTP/TerrainSDK/vtlib/vtosg -L/usr/local/lib
-L/usr/local/lib/netcdf-3 -L/usr/local/lib -L/usr/X11R6/lib  app.o
-lvtosg -lvtdata -lunzip -lgdal -losgDB -losgUtil -losgText
-losgParticle -losg -lOpenThreads -lxmlhelper /usr/local/lib/libMini.a
-lglut -lGLU -lGL -lXmu -lX11 -lXi -lcurl -lbz2 -lm
/home/ericd/work/VTP/TerrainSDK/vtlib/vtosg/libvtosg.so: undefined
reference to `osgDB::writeImageFile(osg::Image const&,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&)'
/home/ericd/work/VTP/TerrainSDK/vtlib/vtosg/libvtosg.so: undefined
reference to `osgText::readFontFile(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)'
/home/ericd/work/VTP/TerrainSDK/vtlib/vtosg/libvtosg.so: undefined
reference to `osg::Drawable::compileGLObjects(osg::State&) const'
/home/ericd/work/VTP/TerrainSDK/vtlib/vtosg/libvtosg.so: undefined
reference to `virtual thunk to osg::NodeVisitor::~NodeVisitor()'
/home/ericd/work/VTP/TerrainSDK/vtlib/vtosg/libvtosg.so: undefined
reference to `virtual thunk to osg::NodeVisitor::~NodeVisitor()'
collect2: ld returned 1 exit status
make[2]: *** [glutSimple] Error 1
make[2]: Leaving directory `/home/ericd/work/VTP/TerrainApps/glutSimple'
make[1]: *** [all] Error 1
make[1]: Leaving directory `/home/ericd/work/VTP/TerrainApps'
make: *** [all] Error 2

#5286 From: "Ben Discoe" <list1@...>
Date: Wed Mar 12, 2008 6:26 pm
Subject: RE: VTP build problem
bdiscoe
Send Email Send Email
 
Eric,

In general, the vtp-unix list is the place to ask Unixy build questions, but,
let me try to help you here in the main list.

Looking at your link messages below, it says it cannot find just a few OSG
symbols.  The most likely explanation is that you are compiling against one
version of OSG, but linking against another.  Make sure that you have only one
version of OSG on your machine, that /usr/local/lib and /usr/local/include both
have exactly what you expect, and you should be OK.

-Ben

> -----Original Message-----
> From: emagnet.geo
> Sent: Wednesday, March 12, 2008 12:00 AM
>
> I am attempting to build VTP in Ubuntu Linux. Worked through a
> seemingly endless series of dependency issues until I got to
> glutSimple. Does anyone know how to resolve this?
>
> TIA -Eric
>
>
> make[2]: Entering directory `/home/ericd/work/VTP/TerrainApps/glutSimple'
> g++ -o glutSimple -L/usr/local/lib
> ... -losgDB -losgUtil -losg -lOpenThreads ...
> libvtosg.so: undefined reference to `osgDB::writeImageFile(..)'

#5287 From: "Ben Discoe" <list1@...>
Date: Wed Mar 12, 2008 6:33 pm
Subject: RE: running wxenviro from a dll
bdiscoe
Send Email Send Email
 
> -----
> From: Bryan Berg
> Sent: Tuesday, March 04, 2008 1:22 PM
> To: vtp@yahoogroups.com
> Subject: RE: [vtp] running wxenviro from a dll
>
> Right . but we do need the paging tile set component of enviro.

The paging tile set functionality is a core part of vtlib.  You don't need
Enviro for that.  Any terrain can be loaded and rendered with the simple methods
you see in any of the Simple apps.

> Can one of the other simple apps do that - if say vtbuilder has already
> been run to create the tile sets ?

Yes.  It doesn't matter if a terrain has tilesets or not.

-Ben

#5288 From: "Bryan Berg" <bberg@...>
Date: Thu Mar 13, 2008 12:35 am
Subject: building mfcSimple
bberg@...
Send Email Send Email
 
Hi there,



I'm trying to build mfcSimple but am getting the error:



fatal error LNK1104: cannot open file 'mfc42d.lib'



A google search reveals that this lib is in VS 6.0; I'm using VS 2005 (and
openned that solution)



I'm thinking I need some mfc lib for vc8.



Thanks !



Bryan



[Non-text portions of this message have been removed]

#5289 From: "Ben Discoe" <list1@...>
Date: Thu Mar 13, 2008 3:15 am
Subject: RE: building mfcSimple
bdiscoe
Send Email Send Email
 
Bryan,

Do you have a strong need or desire to use MFC?  Microsoft has been trying to
discontinue it for years; starting with ATL and then .NET etc.  VC 2005 does not
even include MFC at all (at least the express edition doesn't) which is the most
likely explanation of your link message.

If you need a C++ GUI framework, wxWidgets is better than MFC in every way:
portable, open source, and not ugly inside.  MFC is something of a joke, note
that Microsoft themselves never actually used it for any of their own apps.

-Ben

> -----Original Message-----
> From: vtp@yahoogroups.com [mailto:vtp@yahoogroups.com] On Behalf Of Bryan
> Berg
> Sent: Wednesday, March 12, 2008 2:36 PM
> To: vtp@yahoogroups.com
> Subject: [vtp] building mfcSimple
>
> Hi there,
> I'm trying to build mfcSimple but am getting the error:
>
> fatal error LNK1104: cannot open file 'mfc42d.lib'
>
> A google search reveals that this lib is in VS 6.0; I'm using VS 2005 (and
> openned that solution)
> I'm thinking I need some mfc lib for vc8.
> Thanks !
> Bryan

#5290 From: "Drew Stainton" <drew.stainton@...>
Date: Thu Mar 13, 2008 3:27 am
Subject: Re: building mfcSimple
drew_stainton
Send Email Send Email
 
Ben,

Although I agree somewhat with your perception of MFC, it may be
important to note that a forthcoming update to Visual Studio 2008
will include a significant update to MFC that will bring it in line
with the rest of Microsoft's user interfaces on Vista and Office.
From what I've read, delivery is expected in the first half of 2008.
It appears Microsoft has given up on trying to kill off MFC and will,
instead support it once again.  I'm guessing that it will only be
included in VS2008 Pro and up.

Cheers,
Drew.

--- In vtp@yahoogroups.com, "Ben Discoe" <list1@...> wrote:
>
> Bryan,
>
> Do you have a strong need or desire to use MFC?  Microsoft has been
trying to discontinue it for years; starting with ATL and then .NET
etc.  VC 2005 does not even include MFC at all (at least the express
edition doesn't) which is the most likely explanation of your link
message.
>
> If you need a C++ GUI framework, wxWidgets is better than MFC in
every way: portable, open source, and not ugly inside.  MFC is
something of a joke, note that Microsoft themselves never actually
used it for any of their own apps.
>
> -Ben
>
> > -----Original Message-----
> > From: vtp@yahoogroups.com [mailto:vtp@yahoogroups.com] On Behalf
Of Bryan
> > Berg
> > Sent: Wednesday, March 12, 2008 2:36 PM
> > To: vtp@yahoogroups.com
> > Subject: [vtp] building mfcSimple
> >
> > Hi there,
> > I'm trying to build mfcSimple but am getting the error:
> >
> > fatal error LNK1104: cannot open file 'mfc42d.lib'
> >
> > A google search reveals that this lib is in VS 6.0; I'm using VS
2005 (and
> > openned that solution)
> > I'm thinking I need some mfc lib for vc8.
> > Thanks !
> > Bryan
>

#5291 From: "qljs qljs" <cdw1984518@...>
Date: Thu Mar 13, 2008 9:15 am
Subject: Several bugs found for Chinese version
cdw1984518@...
Send Email Send Email
 
Since I began to use the VTP software, I've being bothered by bugs.
After having fixed, or make detours of these bug, I found that most of
bugs existed just for the internationalization.

I use the Chinese version. My computer has installed the Chinese
version of Windows XP. The words in the menu and dialog of VTP are all
Chinese characters.

These bugs included:
1. VTBuilder, in some occasion, cann't read files if the path to the
file include Chinese characters. According to Ben's explanation, it's
Gdal's fault.

2. In my computer, VTBuilder cann't read an imaginary file which is in
tiff format. After I have deleted all the files under "C:\Program
Files\VTP\Apps\zh", the program has English menus. And, everything is
OK. The file can be read. I haven't read the code to find the bug, But
I am sure that it's internationalization that bring the bug to life.

#5292 From: "Ben Discoe" <list1@...>
Date: Thu Mar 13, 2008 9:23 am
Subject: RE: Several bugs found for Chinese version
bdiscoe
Send Email Send Email
 
Qljs,

Just FYI, there should never be any need to delete i18n files.  To run a VTP app
with another language (locale), just use the command-line argument -locale. 
(It's mentioned at http://vterrain.org/Implementation/i18n.html)  For example,
to run Enviro in English on a computer with non-English default, use

wxEnviro.exe -locale=en

If you have a repeatable case of the TIF not loading with zh locale, which is
not the known problem of Chinese characters in the filename, then please send me
the debug.txt file.

-Ben

> -----
> From: qljs
> Sent: Wednesday, March 12, 2008 11:15 PM
>
> [...]
>
> 2. In my computer, VTBuilder cann't read an imaginary file which is in
> tiff format. After I have deleted all the files under "C:\Program
> Files\VTP\Apps\zh", the program has English menus. And, everything is
> OK. The file can be read. I haven't read the code to find the bug, But
> I am sure that it's internationalization that bring the bug to life.

#5293 From: "gtafricke" <fricke@...>
Date: Wed Mar 19, 2008 7:50 pm
Subject: Linear Structures
gtafricke
Send Email Send Email
 
Hi,

as I can tell, linear structures like fences are around for some time.
Should it be possible to save a layer with those structures (or is
this not yet completely implemented like for the Powerlines)? If I
make a new layer, put in a standard fence, save the layer and reopen
the fence is not displayed. Even worse when I try to zoom to the
fence, enviro crashes. Zooming to a fence works if the layer was not
saved and reloaded first. Is there something wrong with the language
maybe? I tried on a German and on a Belgium PC. One with XP and one
with VISTA.
Same effect on both.

Any one can help?

The file is as follows:
<?xml version="1.0"?>

<StructureCollection xmlns="http://www.openplans.net"
					  xmlns:gml="http://www.opengis.net/gml"
					  xmlns:xlink="http://www.w3.org/1999/xlink"
					  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
					  xsi:schemaLocation="http://www.openplans.net/buildings.xsd">

	 <gml:boundedBy>
		 <gml:Box>
			 <gml:coordinates>150256.452636719,170291.451453125
150391.605468750,170408.223914062</gml:coordinates>
		 </gml:Box>
	 </gml:boundedBy>

	 <SRS>PROJCS["Belge 1972 / Belgian Lambert
72",GEOGCS["Belge72",DATUM["Belge72",SPHEROID["International_1924",6378388,297.0\
000000000601]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJEC\
TION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",51.166667222\
2222],PARAMETER["standard_parallel_2",49.8333338888889],PARAMETER["latitude_of_o\
rigin",90],PARAMETER["central_meridian",4.36748666666667],PARAMETER["false_easti\
ng",150000.013],PARAMETER["false_northing",5400088.438],UNIT["Meter",1]]</SRS>

	 <Linear>
		 <Path>
			 <gml:coordinates>150330.488,170408.224 150391.605,170394.165
150341.46,170318.106 150256.453,170291.451</gml:coordinates>
		 </Path>
		 <Posts Type="wood" Spacing="2.50" Height="1.20" Size="0.13,0.13" />
		 <Connect Type="1" />
	 </Linear>
</StructureCollection>

#5294 From: "Bryan Berg" <bberg@...>
Date: Mon Mar 24, 2008 6:27 pm
Subject: build errros from incorporating mfcsimple into existing app
bberg@...
Send Email Send Email
 
Hi all,



I posted a bit back (bit back ?) about using mfcsimple in vs2005.



I'm currently using vs2003 and trying to integrate the terrain functionality
into an existing mfc app (hence the reason to use mfc in the first place).



I'm not sure if I've included the right code, but right now I'm just trying
to build the new app with the vtosg and vtdata projects added.



Actually the only code I'm using right now is the createScene() method.



These separate projects build fine on their own, but when inside my existing
app I'm getting errors taking me to these projects (listed below).



My thoughts are that this relates to some settings/configuration issue, or
maybe I'm missing a header file; but I haven't been able to track it down.



Of course I also have these VS2003 errors at the bottom to contend with:
after some googling I'm also wondering if the Unicode build has something to
do with it (that is -

The vterrain apps are built in unicode, while my existing app is not).



Thanks !



Bryan



c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(85):
error C2143: syntax error : missing ';' before '*'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(85):
error C2433: 'vtStructure3d::vtGeom' : 'virtual' not permitted on data
declarations

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(85):
error C2501: 'vtStructure3d::vtGeom' : missing storage-class or type
specifiers

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(85):
error C2501: 'vtStructure3d::GetGeom' : missing storage-class or type
specifiers

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(85):
warning C4183: 'GetGeom': missing return type; assumed to be a member
function returning 'int'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(150):
error C2143: syntax error : missing ';' before '*'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(150):
error C2501: 'vtStructInstance3d::vtGeom' : missing storage-class or type
specifiers

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Structure3d.h(150):
error C2501: 'vtStructInstance3d::m_pHighlight' : missing storage-class or
type specifiers

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\TerrainLayers.h(63):
error C2143: syntax error : missing ';' before '*'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\TerrainLayers.h(63):
error C2501: 'vtImageLayer::vtMultiTexture' : missing storage-class or type
specifiers

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\TerrainLayers.h(63):
error C2501: 'vtImageLayer::m_pMultiTexture' : missing storage-class or type
specifiers

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(20):
error C2065: 'vtMesh' : undeclared identifier

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(20):
error C2059: syntax error : '>'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(22):
error C2143: syntax error : missing ';' before '}'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(73):
error C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(84):
error C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(85):
error C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(86):
error C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(116):
error C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(118):
error C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\AbstractLayer.h(160):
error C2143: syntax error : missing ';' before '}'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(36): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(39): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(48): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(50): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(50): error
C2065: 'ptr' : undeclared identifier

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(55): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(57): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(58): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(75): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(76): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(79): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(81): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(82): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(91): error
C2143: syntax error : missing ';' before '}'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(96): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(99): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(101): error
C2065: 'bEnabledOnly' : undeclared identifier

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(102): error
C2143: syntax error : missing ';' before '}'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(103): error
C2143: syntax error : missing ';' before '}'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(115): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(118): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(122): error
C2146: syntax error : missing ',' before identifier 'my'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(122): error
C2065: 'my' : undeclared identifier

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(122): error
C2143: syntax error : missing ',' before ')'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(132): error
C2143: syntax error : missing ';' before '}'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(139): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(142): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(144): error
C2143: syntax error : missing ';' before '{'

c:\vterrain\vtp-src-080114\VTP\TerrainSDK\vtlib\core\Engine.h(150): error
C2143: syntax error : missing ';' before '}'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(17):
error C2143: syntax error : missing ';' before '{'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(21):
error C2947: expecting '>' to terminate template-argument-list, found '>'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(21):
error C2976: 'std::vector' : too few template arguments

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\vector(896) : see declaration of 'std::vector'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(22):
error C2955: 'std::vector' : use of class template requires template
argument list

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\vector(896) : see declaration of 'std::vector'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(22):
error C2955: 'std::vector' : use of class template requires template
argument list

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\vector(896) : see declaration of 'std::vector'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(23):
error C2236: unexpected 'class' 'vtVisual::_List_nod'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(27):
error C2899: typename cannot be used outside a template declaration

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(28):
error C2903: 'rebind' : symbol is neither a class template nor a function
template

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(28):
error C2027: use of undefined type '_Alloc'

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(21) : see declaration of '_Alloc'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(28):
error C2143: syntax error : missing ';' before '<'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(28):
error C2039: 'other' : is not a member of 'operator``global namespace'''

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(28):
error C2238: unexpected token(s) preceding ';'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2146: syntax error : missing ')' before identifier '_Nextarg'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2146: syntax error : missing ';' before identifier '_Nextarg'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2460: 'vtVisual::_List_nod::_Node::_Genptr' : uses
'vtVisual::_List_nod::_Node', which is being defined

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(31) : see declaration of 'vtVisual::_List_nod::_Node'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2501: 'vtVisual::_List_nod::_Node::_Nextarg' : missing storage-class
or type specifiers

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2146: syntax error : missing ';' before identifier '_Prevarg'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2501: 'vtVisual::_List_nod::_Node::_Genptr' : missing storage-class
or type specifiers

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2501: 'vtVisual::_List_nod::_Node::_Prevarg' : missing storage-class
or type specifiers

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2143: syntax error : missing ';' before '&'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2501: 'vtVisual::_List_nod::_Node::_Ty' : missing storage-class or
type specifiers

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
warning C4228: nonstandard extension used : qualifiers after comma in
declarator list are ignored

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(32):
error C2059: syntax error : ')'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(33):
error C2065: '_Nextarg' : undeclared identifier

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(33):
error C3861: '_Next': identifier not found, even with argument-dependent
lookup

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(33):
error C2531: 'vtVisual::_List_nod::_Node::_Myvalarg' : reference to a bit
field illegal

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(33):
error C2501: 'vtVisual::_List_nod::_Node::_Myvalarg' : missing storage-class
or type specifiers

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(33):
error C2061: syntax error : identifier '_Prevarg'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(33):
error C2061: syntax error : identifier '_Myvalarg'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(35):
error C2143: syntax error : missing ';' before '{'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(35):
error C2334: unexpected token(s) preceding '{'; skipping apparent function
body

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(42):
error C2146: syntax error : missing ')' before identifier '_Al'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(42):
error C2146: syntax error : missing ';' before identifier '_Al'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(42):
error C2079: 'vtVisual::_List_nod::_Node::_Alloc' uses undefined class
'vtVisual::_List_nod'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(42):
error C2059: syntax error : ')'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(43):
error C2065: '_Al' : undeclared identifier

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(43):
error C3861: '_Alnod': identifier not found, even with argument-dependent
lookup

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(44):
error C2501: 'vtVisual::_List_nod::_Node::_Al' : missing storage-class or
type specifiers

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(47):
error C2899: typename cannot be used outside a template declaration

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(47):
error C2903: 'rebind' : symbol is neither a class template nor a function
template

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(47):
error C2027: use of undefined type '_Alloc'

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(21) : see declaration of '_Alloc'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(47):
error C2143: syntax error : missing ';' before '<'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(47):
error C2377: 'vtVisual::_List_nod::rebind' : redefinition; typedef cannot be
overloaded with any other symbol

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(28) : see declaration of 'vtVisual::_List_nod::rebind'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(48):
error C2039: 'other' : is not a member of 'operator``global namespace'''

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(48):
error C2238: unexpected token(s) preceding ';'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(49):
error C2208: 'vtVisual::_List_nod' : no members defined using this type

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(55):
error C2143: syntax error : missing ',' before '<'

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(69) : see reference to class template instantiation
'vtVisual::_List_ptr<_Ty,_Alloc>' being compiled

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(58):
error C2059: syntax error : '<'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(58):
error C2039: '_Node' : is not a member of 'operator``global namespace'''

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(58):
error C2238: unexpected token(s) preceding ';'

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(100):
error C2059: syntax error : '<'

         c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(966) : see reference to class template instantiation
'vtVisual::list<_Ty,_Ax>' being compiled

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(100):
error C2039: '_Genptr' : is not a member of 'operator``global namespace'''

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(100):
error C2238: unexpected token(s) preceding ';'



[Non-text portions of this message have been removed]

#5295 From: "Bryan Berg" <bberg@...>
Date: Tue Mar 25, 2008 9:05 pm
Subject: Re: build errros from incorporating mfcsimple into existing app
bberg@...
Send Email Send Email
 
No sweat,



I hadn't included the preprocessor definitions in my new project:



VTDEBUG

VTLIB_OSG=1



-Bryan





[Non-text portions of this message have been removed]

#5296 From: "Ben Discoe" <ben@...>
Date: Thu Apr 3, 2008 8:30 am
Subject: ArcGIS Explorer
bdiscoe
Send Email Send Email
 
Hi Philip,

Thanks for the note.  I did not know that ArcGIS Explorer was fully released
yet, i just heard about it as beta last year.  I spent some time to install and
try it today.

Overall, it ran very poorly.  Paging was very slow - zooming into my island,
what takes 5 seconds to download in Google Earth took 2 minutes in ArcGE.  When
i loaded a vector shapefile, it insisted on displaying it as a raster, which
looked horribly aliased - slightly better after zooming in, but still bad
aliasing.  The UI was highly lagged - trying to rotate the camera, it responded
to where my mouse was seconds before, the latency was that bad.  Several times,
cpu usage went to 100% and it made my entire OS almost non-responsive, mouse
moving in rough steps.  I had to kill the ArcGE task ("E2.exe") several times,
then gave up on it.

One very impressive thing that ArcGE did let me do was to use my own elevation
data - i tried bringing in a USGS DEM, and it worked.  This is the #1 thing i
find lacking in Google Earth, so the fact that ArcGE can do it, i find very
significant.  However, ArcGE subsequently brought my machine to a crawl, and i
had to kill it again, so i could not get a good look at how it would render the
DEM.  Maybe when ArcGE becomes more stable, i could give it a proper review.

I have updated http://vterrain.org/Packages/earth_viewers.html

As far as i know, MS Virtual Earth is just a Internet Explorer plugin, not an
actual application.  I can't imagine anyone doing anything real inside the
(security necessity) limited sandbox of a browser.  Or do you know if MSVE
available as an actual app?

-Ben

> -----Original Message-----
> From: Philip Paar [mailto:paar@...]
> Sent: Wednesday, March 26, 2008 6:27 AM
> To: Ben Discoe
>
> Hi Ben,
> [...]
>
> I wonder if you are considering to update your earth viewer comparison
> chart?
> You might wanna check out the current release of the free ESRI ArcGIS
> Explorer. It has become quite a powerful tool. With Arc Online ESRI is
> offering commercial geodata for free use in ArcGIS, Globe Explorer
> etc. it also can connect to OGC webservices or ArcGIS Server to
> perform sophisticated GIS operations on servers.
> http://www.esri.com/software/arcgis/explorer/
>
> Also MS Virtual Earth is missing your table.
>
> -Philip

#5297 From: "Bryan Berg" <bberg@...>
Date: Fri Apr 4, 2008 10:43 pm
Subject: can vterrain sleep ?
bberg@...
Send Email Send Email
 
If humans need sleep, shouldn't vterrain ?



: * )~



Actually, this (serious) question stems from integrating vterrain's
functionality into an existing mfc/opengl app.



Maybe the fact that we're using mfc is part of the problem, but right now
that's what we got.



Anyways,



Our app doesn't seem to be functioning properly when the vterrain engines
are incorporated.



The cpu for vterrain is always at 25%, even when we're not doing anything.



Maybe if the vterrain app got some rest the other app could do what it
should.



Any ideas ?



Ie - does vterrain have some sleep method ?



I'm pretty much just working from the mfcSimple example, although some
enviro - for cursor information (long/lat/elevation).



In the future I'll be working more with enviro though.



Thanks !!!



: * )~



-Bryan



[Non-text portions of this message have been removed]

#5298 From: "Ben Discoe" <list1@...>
Date: Sat Apr 5, 2008 12:41 am
Subject: RE: can vterrain sleep ?
bdiscoe
Send Email Send Email
 
Bryan,

The short answer is yes, vtlib applications can sleep.  In fact, it's entirely
up to your own event handling, which is in your own app.  There are many ways to
render continuously, so depending on how you are doing it, you can just stop.

1. If you are using Idle events, don't render on Idle events.
2. If you are using a Timer, don't render on Timer events.
3. If you are using refresh-on-paint, don't refresh after you paint.

If you are basing your app on mfcSimple, it uses (3) refresh-on-paint.  To
sleep, in your OnPaint(), don't call InvalidateRect.  If you still need your app
to "wake up" from sleeping, e.g. whenever the user moves the camera, then do
call InvalidateRect whenever you receive UI events.

-Ben

> -----Original Message-----
> From: vtp@yahoogroups.com [mailto:vtp@yahoogroups.com] On Behalf Of Bryan
> Berg
> Sent: Friday, April 04, 2008 12:44 PM
> To: vtp@yahoogroups.com
>
> If humans need sleep, shouldn't vterrain ?
> : * )~
> Actually, this (serious) question stems from integrating vterrain's
> functionality into an existing mfc/opengl app.
> Maybe the fact that we're using mfc is part of the problem, but right now
> that's what we got. Anyways,
> Our app doesn't seem to be functioning properly when the vterrain engines
> are incorporated.
> The cpu for vterrain is always at 25%, even when we're not doing anything.
> Maybe if the vterrain app got some rest the other app could do what it
> should.
> Any ideas ?
> Ie - does vterrain have some sleep method ?
> I'm pretty much just working from the mfcSimple example, although some
> enviro - for cursor information (long/lat/elevation).
> In the future I'll be working more with enviro though.
> Thanks !!!
> : * )~
> -Bryan

#5299 From: "gtafricke" <fricke@...>
Date: Mon Apr 7, 2008 7:26 am
Subject: Re: VTP web plugin (vtocx)
gtafricke
Send Email Send Email
 
Hi,

I finally got around to testing the web plugin. I think it's quite
promising. For future development we should have in mind to maybe use
web services like W3DS (www.citygml.org) and WTS/WFS in realtime
rather than only focusing on predefined terrains. I've actually had
questions form users side in that direction already for Enviro.

- Lars


--- In vtp@yahoogroups.com, "Ben Discoe" <ben@...> wrote:
>
> The VTP runtime is very flexible.  It can run inside almost any
application framework, on any platform, including an ActiveX control
(.ocx), for embedding a 3D scene inside a web page viewed with
Internet Explorer (or any other OLE container).  There is now a very
simple example, vtocx, which shows how to do this.  It is (so far) a
very basic 'alpha release'.
>
> For those interested, please check out:
> http://vterrain.org/Doc/vtocx.html
>
> There is a binary provided, for those on Windows to use with
Internet Explorer, so you don't need to be a programmer to use it.
There is also source code checked into SVN.  Please send feedback; if
vtocx works without any major problems, i'll add it to the next
official VTP release.
>
> Note that the terrain data does still need to be on a filesystem
that your computer can access, i.e. not a URL.
>
> -Ben
>

#5300 From: "Roger James" <roger@...>
Date: Mon Apr 7, 2008 1:33 pm
Subject: Holy buildings Batman!
rogerjames99
Send Email Send Email
 
Ben,



Here is my first pass at rendering buildings with holes. I have not checked
it in as there is a major hack in
FelkelIntersection::ApplyNonconvexIntersection. The hack disables a safety
check that is only valid for single polygon buildings but is definitely
needed. The code should not be a regression for single polygon buildings but
some multiple polygon buildings could fail or loop. It is one of those
problems that are extremely difficult to track down until you come across
some simple data that can reliably reproduce it. I have not got any and have
only tested this code against a simple handcrafted test case.



I have copied this to the list in the hope that someone else with a younger
brain and better math than me will try it out and review the code. I have
made this plea a number of times in the past and got no takers! So come on
someone, please step up to the plate.



I have not modified the code in Building3d.cpp that only invokes felkel for
buildings with more than 4 edges, so if you want felkel invoked for those
cases you will need to change that.



Roger


   ----------

//
// FelkelStraightSkeleton.cpp: implementation of the vtStraightSkeleton class.
//
// Copyright (c) 2003-2006 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//
// Straight skeleton algorithm and original implementation
// courtesy of Petr Felkel and Stepan Obdrzalek (petr.felkel@...)
// Re-implemented for the Virtual Terrain Project (vterrain.org)
// by Roger James (www.beardandsandals.co.uk)
//

#include "FelkelStraightSkeleton.h"
#include "vtdata/vtString.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

vtStraightSkeleton::vtStraightSkeleton()
{

}

vtStraightSkeleton::~vtStraightSkeleton()
{

}

CSkeleton& vtStraightSkeleton::MakeSkeleton(ContourVector &contours)
{
	 try
	 {
		 while (m_iq.size ())
			 m_iq.pop ();
		 m_vl.erase(m_vl.begin(), m_vl.end());
		 m_skeleton.erase(m_skeleton.begin(), m_skeleton.end());
		 m_boundaryedges.erase(m_boundaryedges.begin(), m_boundaryedges.end());

		 for (size_t ci = 0; ci < contours.size(); ci++)
		 {
			 Contour &points = contours[ci];

			 Contour::iterator first = points.begin();
			 if (first == points.end())
				 break;

			 Contour::iterator next = first;

			 while (++next != points.end ())
			 {
				 if (*first == *next)
					 points.erase (next);
				 else
					 first = next;
				 next = first;
			 }

			 int s = points.size();
			 CVertexList::iterator start = m_vl.end();
			 CVertexList::iterator from = start;
			 CVertexList::iterator to = start;

			 for (int f = 0; f <= s; f++)
			 {
				 if (0 == f)
				 {
					 m_vl.push_back(CVertex(points[0].m_Point, points[s - 1].m_Point, points[s -
1].m_Slope, points[1].m_Point, points[0].m_Slope));
					 to = m_vl.end();
					 to--;
					 start = to;
				 }
				 else if (f == s)
				 {
					 from = to;
					 to = start;
					 m_boundaryedges.push_front(CSkeletonLine(*from, *to));
				 }
				 else
				 {
					 from = to;
					 m_vl.push_back(CVertex(points[f].m_Point, points[f - 1].m_Point, points[f -
1].m_Slope, points[(f + 1) % s].m_Point, points[f].m_Slope));
					 to = m_vl.end();
					 to--;
					 m_boundaryedges.push_front(CSkeletonLine(*from, *to));
				 }
			 }
		 }

		 m_NumberOfBoundaryVertices = m_vl.size();
		 m_NumberOfBoundaryEdges = m_boundaryedges.size();

		 if (m_vl.size() < 3)
		 {
			 vtString *str = new vtString;
			 str->Format("%s (%d): Eave Polygon too small\n", __FILE__, __LINE__);
			 throw str;
		 }

		 CVertexList::iterator i;

		 size_t vn = 0, cn = 0;

		 CVertexList::iterator contourBegin;

		 for (i = m_vl.begin (); i != m_vl.end (); i++)
		 {
			 (*i).m_prevVertex = &*m_vl.prev(i);
			 (*i).m_nextVertex = &*m_vl.next(i);
			 (*i).m_leftVertex = &*i;
			 (*i).m_rightVertex = &*i;
			 if (vn == 0)
				 contourBegin = i;
			 if (vn == contours [cn].size () - 1)
			 {
				 (*i).m_nextVertex = &*contourBegin;
				 (*contourBegin).m_prevVertex = &*i;
				 vn = 0;
				 cn ++;
			 }
			 else
				 vn ++;
		 }


#ifdef FELKELDEBUG
		 VTLOG("Building initial intersection queue\n");
#endif
		 for (i = m_vl.begin(); i != m_vl.end (); i++)
		 {
			 if (!(*i).m_done)
			 {
				 CIntersection is(m_vl, *i);
				 if (is.m_height != CN_INFINITY)
					 m_iq.push(is);
			 }
		 }

#ifdef FELKELDEBUG
		 VTLOG("Processing intersection queue\n");
#endif
		 while (m_iq.size ())
		 {
			 CIntersection i = m_iq.top ();

			 m_iq.pop ();

#ifdef FELKELDEBUG
			 VTLOG("Processing %d %d left done %d right done %d\n",
				 i.m_leftVertex->m_ID, i.m_rightVertex->m_ID, i.m_leftVertex->m_done,
i.m_rightVertex->m_done);
#endif
			 if ((NULL == i.m_leftVertex) || (NULL == i.m_rightVertex))
			 {
				 vtString *str = new vtString;
				 str->Format("%s (%d): Invalid intersection queue entry\n", __FILE__,
__LINE__);
				 throw str;
			 }
			 if (i.m_leftVertex->m_done && i.m_rightVertex->m_done)
				 continue;
			 if (i.m_leftVertex->m_done || i.m_rightVertex->m_done)
			 {
				 if (!i.m_leftVertex->m_done)
					 m_iq.push(CIntersection (m_vl, *i.m_leftVertex));
				 if (!i.m_rightVertex->m_done)
					 m_iq.push(CIntersection (m_vl, *i.m_rightVertex));
				 continue;
			 }

#ifdef FELKELDEBUG
			 if (!(i.m_leftVertex->m_prevVertex != i.m_rightVertex))
				 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
			 if (!(i.m_rightVertex->m_nextVertex != i.m_leftVertex))
				 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
#endif
			 if (i.m_type == CIntersection::CONVEX)
				 if (i.m_leftVertex->m_prevVertex->m_prevVertex == i.m_rightVertex ||
i.m_rightVertex->m_nextVertex->m_nextVertex == i.m_leftVertex)
					 i.ApplyLast3(m_skeleton, m_vl);
				 else
					 i.ApplyConvexIntersection(m_skeleton, m_vl, m_iq);
			 if (i.m_type == CIntersection :: NONCONVEX)
				 i.ApplyNonconvexIntersection(m_skeleton, m_vl, m_iq, cn == 1);
		 }

#ifdef FELKELDEBUG
		 Dump();
#endif

		 FixSkeleton();

#ifdef FELKELDEBUG
		 Dump();
#endif
	 }
	 catch (vtString *str)
	 {
		 m_skeleton.erase(m_skeleton.begin(), m_skeleton.end());
		 VTLOG(*str);
		 delete str;
	 }

	 return m_skeleton;
}

CSkeleton& vtStraightSkeleton::MakeSkeleton(Contour &points)
{
	 ContourVector vv;

	 vv.push_back (points);

	 return MakeSkeleton(vv);
}

CSkeleton vtStraightSkeleton::CompleteWingedEdgeStructure(ContourVector
&contours)
{
	 // Save current skeleton
	 int iOldSize = m_skeleton.size();
	 int i;
	 CSkeleton::iterator si;

	 for (size_t ci = 0; ci < contours.size(); ci++)
	 {
		 Contour& points = contours[ci];
		 for (size_t pi = 0; pi < points.size(); pi++)
		 {
			 C3DPoint& LowerPoint = points[pi].m_Point;
			 C3DPoint& HigherPoint = points[(pi+1)%points.size()].m_Point;


			 // Find a matching empty lower left
			 for (i = 0, si = m_skeleton.begin(); i < iOldSize; i++, si++)
			 {
				 CSkeletonLine& Line = *si;
				 if ((Line.m_lower.m_vertex->m_point == LowerPoint) && (Line.m_lower.LeftID()
== -1))
					 break;
			 }
			 if (i == iOldSize)
			 {
				 VTLOG("CompleteWingedEdgeStructure - Failed to find matching empty lower
left\n");
				 return CSkeleton();
			 }
			 CSkeletonLine& OldLowerLeft = *si;

			 // Find a matching empty lower right
			 for (i = 0, si = m_skeleton.begin(); i < iOldSize; i++, si++)
			 {
				 CSkeletonLine& Line = *si;
				 if ((Line.m_lower.m_vertex->m_point == HigherPoint) &&
(Line.m_lower.RightID() == -1))
					 break;
			 }
			 if (i == iOldSize)
			 {
				 VTLOG("CompleteWingedEdgeStructure - Failed to find matching empty lower
right\n");
				 return CSkeleton();
			 }
			 CSkeletonLine& OldLowerRight = *si;

			 m_skeleton.push_back(CSkeletonLine(*OldLowerLeft.m_lower.m_vertex,
*OldLowerRight.m_lower.m_vertex));

			 CSkeletonLine& NewEdge = m_skeleton.back();

			 NewEdge.m_lower.m_right = &OldLowerLeft;
			 OldLowerLeft.m_lower.m_left = &NewEdge;
			 NewEdge.m_higher.m_left = &OldLowerRight;
			 OldLowerRight.m_lower.m_right = &NewEdge;
		 }
	 }
#ifdef FELKELDEBUG
	 Dump();
#endif
	 return m_skeleton;
}

void vtStraightSkeleton::FixSkeleton()
{
	 // Search the skeleton list for consecutive pairs of incorrectly linked lines
	 CSkeleton::iterator s1 = m_skeleton.begin();
	 for (unsigned int i = 0; i < m_skeleton.size() - 2; i++, s1++)
	 {
		 CSkeletonLine& Lower = *s1++;
		 CSkeletonLine& Higher1 = *s1++;
		 CSkeletonLine& Higher2 = *s1;

		 if ((Higher1.m_higher.RightID() == -1) &&
			 (Higher1.m_lower.LeftID() == -1) &&
			 (Higher2.m_higher.LeftID() == -1) &&
			 (Higher2.m_lower.RightID() == -1) &&
			 (Higher1.m_higher.VertexID() == Higher2.m_lower.VertexID()) &&
			 (Higher1.m_lower.VertexID() == Higher2.m_higher.VertexID())) // I don't think
I cam make this test much tighter !!!
		 {
			 CSkeletonLine* pLeft = Lower.m_higher.m_left;
			 CSkeletonLine* pRight = Lower.m_higher.m_right;
			 const CVertex* pVertex = Lower.m_higher.m_vertex;
			 if ((NULL == pLeft) || (NULL == pRight) || (NULL == pVertex))
			 {
				 vtString *str = new vtString;
				 str->Format("%s (%d): Problem fixing skeleton\n", __FILE__, __LINE__);
				 throw str;
			 }
			 // Fix up the left side
			 if ((pLeft->m_lower.VertexID() == pVertex->m_ID) ||
(pLeft->m_lower.VertexID() == pVertex->m_ID + 1))
			 {
				 // Fix up lower end
				 pLeft->m_lower.m_vertex = pVertex;
				 pLeft->m_lower.m_left = pRight;
				 if (pLeft->m_lower.RightID() != Lower.m_ID)
				 {
					 vtString *str = new vtString;
					 str->Format("%s (%d): Left Lower Right ID != Lower ID\n", __FILE__,
__LINE__);
					 throw str;
				 }
			 }
			 else if ((pLeft->m_higher.VertexID() == pVertex->m_ID) ||
(pLeft->m_higher.VertexID() == pVertex->m_ID + 1))
			 {
				 // Fix up upper end
				 pLeft->m_higher.m_vertex = pVertex;
				 pLeft->m_higher.m_left = pRight;
				 if (pLeft->m_higher.RightID() != Lower.m_ID)
				 {
					 vtString *str = new vtString;
					 str->Format("%s (%d): Left Higher Right ID != Lower ID\n", __FILE__,
__LINE__);
					 throw str;
				 }
			 }
			 else
			 {
				 vtString *str = new vtString;
				 str->Format("%s (%d): Problem fixing left side\n", __FILE__, __LINE__);
				 throw str;
			 }
			 // Fix up the right side
			 if ((pRight->m_lower.VertexID() == pVertex->m_ID) ||
(pRight->m_lower.VertexID() == pVertex->m_ID + 1))
			 {
				 // Fix up lower end
				 pRight->m_lower.m_vertex = pVertex;
				 pRight->m_lower.m_right = pLeft;
				 if (pRight->m_lower.LeftID() != Lower.m_ID)
				 {
					 vtString *str = new vtString;
					 str->Format("%s (%d): Right Lower Left ID != Lower ID\n", __FILE__,
__LINE__);
					 throw str;
				 }
			 }
			 else if ((pRight->m_higher.VertexID() == pVertex->m_ID) ||
(pRight->m_higher.VertexID() == pVertex->m_ID + 1))
			 {
				 // Fix up upper end
				 pRight->m_higher.m_vertex = pVertex;
				 pRight->m_higher.m_right = pLeft;
				 if (pRight->m_higher.LeftID() != Lower.m_ID)
				 {
					 vtString *str = new vtString;
					 str->Format("%s (%d): Right Higher Left ID != Lower ID\n", __FILE__,
__LINE__);
					 throw str;
				 }
			 }
			 else
			 {
				 vtString *str = new vtString;
				 str->Format("%s (%d): FixSkeleton - Problem fixing right side\n", __FILE__,
__LINE__);
				 throw str;
			 }
		 }
		 s1--;
		 s1--;
	 }
}

#ifdef FELKELDEBUG
void vtStraightSkeleton::Dump()
{
	 int i;

	 VTLOG("Skeleton:\n");

	 i = 0;
	 for (CSkeleton::iterator s1 = m_skeleton.begin(); s1 != m_skeleton.end(); s1++)
	 {
		 CSkeletonLine& db = (*s1);
		 VTLOG("ID: %d lower leftID %d rightID %d vertexID %d (%f %f %f)\nhigher leftID
%d rightID %d vertexID %d (%f %f %f)\n",
			 db.m_ID,
			 db.m_lower.LeftID(),
			 db.m_lower.RightID(),
			 db.m_lower.VertexID(), db.m_lower.m_vertex->m_point.m_x,
db.m_lower.m_vertex->m_point.m_y, db.m_lower.m_vertex->m_point.m_z,
			 db.m_higher.LeftID(),
			 db.m_higher.RightID(),
			 db.m_higher.VertexID(), db.m_higher.m_vertex->m_point.m_x,
db.m_higher.m_vertex->m_point.m_y, db.m_higher.m_vertex->m_point.m_z);
	 }
}
#endif

   ----------

//
// Building3d.cpp
//
// The vtBuilding3d class extends vtBuilding with the ability to procedurally
// create 3D geometry of the buildings.
//
// Copyright (c) 2001-2008 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "vtdata/HeightField.h"
#include "vtdata/Triangulate.h"
#include "vtdata/PolyChecker.h"

#include "Light.h"
#include "Terrain.h"
#include "Building3d.h"
#include "FelkelStraightSkeleton.h"


/////////////////////////////////////////////////////////////////////////////

vtBuilding3d::vtBuilding3d() : vtBuilding()
{
	 m_pContainer = NULL;
	 m_pGeom = NULL;
	 m_pHighlight = NULL;
}

vtBuilding3d::~vtBuilding3d()
{
	 // meshes will be automatically deleted by the geometry they're in
}

vtBuilding3d &vtBuilding3d::operator=(const vtBuilding &v)
{
	 // just call the copy method of the parent class
	 *((vtBuilding*)this) = v;
	 return *this;
}


//
// Convert the building's reference point into world coordinates.
//
void vtBuilding3d::UpdateWorldLocation(vtHeightField3d *pHeightField)
{
	 // Embed the building in the ground such that the lowest corner of its
	 // lowest level is at ground level.
	 float base_level = CalculateBaseElevation(pHeightField);

	 // Find the center of the building in world coordinates (the origin of
	 // the building's local coordinate system)
	 DPoint2 center;
	 GetBaseLevelCenter(center);
	 pHeightField->ConvertEarthToSurfacePoint(center, m_center);
	 m_center.y = base_level;
}

float vtBuilding3d::GetHeightOfStories()
{
	 float height = 0.0f;

	 int levs = m_Levels.GetSize();
	 for (int i = 0; i < levs; i++)
		 height += m_Levels[i]->m_iStories * m_Levels[i]->m_fStoryHeight;

	 return height;
}


void vtBuilding3d::DestroyGeometry()
{
	 if (!m_pGeom) // safety check
		 return;

	 m_pContainer->RemoveChild(m_pGeom);
	 m_pGeom->Release();
	 m_pGeom = NULL;
	 m_Mesh.Empty();
}

void vtBuilding3d::AdjustHeight(vtHeightField3d *pHeightField)
{
	 UpdateWorldLocation(pHeightField);
	 m_pContainer->SetTrans(m_center);
}

void vtBuilding3d::CreateUpperPolygon(vtLevel *lev, FPolygon3 &polygon,
									   FPolygon3 &polygon2)
{
	 int i, prev, next;
	 int rings = polygon.size();

	 polygon2 = polygon;

	 int base_edge = 0;
	 for (int ring = 0; ring < rings; ring++)
	 {
		 FLine3 &poly = polygon[ring];
		 FLine3 &poly2 = polygon2[ring];

		 int edges = poly.GetSize();

		 for (i = 0; i < edges; i++)
		 {
			 prev = (i-1 < 0) ? edges-1 : i-1;
			 next = (i+1 == edges) ? 0 : i+1;

			 FPoint3 p = poly[i];

			 int islope1 = lev->GetEdge(base_edge + prev)->m_iSlope;
			 int islope2 = lev->GetEdge(base_edge + i)->m_iSlope;
			 if (islope1 == 90 && islope2 == 90)
			 {
				 // easy case
				 p.y += lev->m_fStoryHeight;
			 }
			 else
			 {
				 float slope1 = (islope1 / 180.0f * PIf);
				 float slope2 = (islope2 / 180.0f * PIf);

				 // get edge vectors
				 FPoint3 vec1 = poly[prev] - poly[i];
				 FPoint3 vec2 = poly[next] - poly[i];
				 vec1.Normalize();
				 vec2.Normalize();

				 // get perpendicular (upward pointing) vectors
				 FPoint3 perp1, perp2;
				 perp1.Set(0, 1, 0);
				 perp2.Set(0, 1, 0);

				 // create rotation matrices to rotate them upward
				 FMatrix4 mat1, mat2;
				 mat1.Identity();
				 mat1.AxisAngle(vec1, -slope1);
				 mat2.Identity();
				 mat2.AxisAngle(vec2, slope2);

				 // create normals
				 FPoint3 norm1, norm2;
				 mat1.TransformVector(perp1, norm1);
				 mat2.TransformVector(perp2, norm2);

				 // vector of plane intersection is cross product of their normals
				 FPoint3 inter = norm1.Cross(norm2);
				 // Test that intersection vector is pointing into the polygon
				 // need a better test if we are going to handle downward sloping roofs
				 if (inter.y < 0)
					 inter = -inter; // Reverse vector to point upward

				 inter.Normalize();
				 inter *= (lev->m_fStoryHeight / inter.y);

				 p += inter;
			 }
			 poly2[i] = p;
		 }
		 base_edge += edges;
	 }
}

bool vtBuilding3d::CreateGeometry(vtHeightField3d *pHeightField)
{
	 PolyChecker PolyChecker;
	 int i;
	 unsigned int j, k;

	 UpdateWorldLocation(pHeightField);

	 // TEMP: we can handle complex polys now - i think
	 //if (!PolyChecker.IsSimplePolygon(GetLocalFootprint(0)))
	 // return false;

	 // create the edges (walls and roof)
	 float fHeight = 0.0f;
	 int iLevels = GetNumLevels();

	 int level_show = -1, edge_show = -1;
	 GetValueInt("level", level_show);
	 GetValueInt("edge", edge_show);

	 for (i = 0; i < iLevels; i++)
	 {
		 vtLevel *lev = m_Levels[i];
		 const FPolygon3 &foot = GetLocalFootprint(i);
		 unsigned int edges = lev->NumEdges();

		 // safety check
		 if (foot[0].GetSize() < 3)
			 return false;

		 if (lev->IsHorizontal())
		 {
			 // make flat roof
			 AddFlatRoof(foot, lev);
		 }
		 else if (lev->IsUniform())
		 {
			 int iHighlightEdge = level_show == i ? edge_show : -1;
			 CreateUniformLevel(i, fHeight, iHighlightEdge);
			 fHeight += lev->m_iStories * lev->m_fStoryHeight;
		 }
		 else if (lev->HasSlopedEdges() && edges > 4)
		 {
			 // For complicated roofs with sloped edges which meet at a
			 // roofline of uneven height, we need a sophisticated
			 // straight-skeleton solution like Petr Felkel's
			 float fRoofHeight = MakeFelkelRoof(foot, lev);
			 if (fRoofHeight < 0.0)
			 {
				 VTLOG("Failed to make Felkel roof - reverting to flat roof\n");
				 AddFlatRoof(foot, lev);
			 }
			 fHeight += fRoofHeight;
		 }
		 else
		 {
			 // Build a 'flat roof' for the floor
			 AddFlatRoof(foot, lev);

			 FPolygon3 poly = foot;
			 FPolygon3 poly2;

			 // Build a set of walls for each storey of the level
			 for (j = 0; j < lev->m_iStories; j++)
			 {
				 for (unsigned int r = 0; r < poly.size(); r++)
				 {
					 for (k = 0; k < poly[r].GetSize(); k++)
					 {
						 poly[r][k].y = fHeight;
					 }
				 }
				 CreateUpperPolygon(lev, poly, poly2);
				 int edge_start = 0;
				 for (unsigned int r = 0; r < poly.size(); r++)
				 {
					 for (k = edge_start; k < edge_start + poly[r].GetSize(); k++)
					 {
						 bool bShowEdge = (level_show == i && edge_show == k);
						 CreateEdgeGeometry(lev, poly, poly2, k, bShowEdge);
					 }
					 edge_start += poly[r].GetSize();
				 }
				 fHeight += lev->m_fStoryHeight;
			 }
		 }
	 }

#if 0 // testing
	 const FLine3 &roof = GetLocalFootprint(iLevels-1); // roof: top level
	 vtLevel *roof_lev = m_Levels[iLevels-1];
	 float roof_height = (roof_lev->m_fStoryHeight * roof_lev->m_iStories);
#endif

	 // wrap in a shape and set materials
	 m_pGeom = new vtGeom;
	 m_pGeom->SetName2("building-geom");
	 vtMaterialArray *pShared = GetSharedMaterialArray();
	 m_pGeom->SetMaterials(pShared);

	 for (j = 0; j < m_Mesh.GetSize(); j++)
	 {
		 vtMesh *mesh = m_Mesh[j].m_pMesh;
		 int index = m_Mesh[j].m_iMatIdx;
		 m_pGeom->AddMesh(mesh, index);
		 mesh->Release(); // pass ownership
	 }

	 // resize bounding box
	 if (m_pHighlight)
	 {
		 bool bEnabled = m_pHighlight->GetEnabled();

		 m_pContainer->RemoveChild(m_pHighlight);
		 m_pHighlight->Release();

		 FSphere sphere;
		 m_pGeom->GetBoundSphere(sphere);
		 m_pHighlight = CreateBoundSphereGeom(sphere);
		 m_pContainer->AddChild(m_pHighlight);

		 m_pHighlight->SetEnabled(bEnabled);
	 }
	 return true;
}


////////////////////////////////////////////////////////////////////////////

//
// Since each set of primitives with a specific material requires its own
// mesh, this method looks up or creates the mesh as needed.
//
vtMesh *vtBuilding3d::FindMatMesh(const vtString &Material,
								   const RGBi &color, vtMesh::PrimType ePrimType)
{
	 int mi;
	 int VertType;
	 RGBf fcolor = color;

	 // wireframe is a special case, used for highlight materials
	 if (ePrimType == vtMesh::LINE_STRIP)
	 {
		 mi = FindMatIndex(BMAT_NAME_HIGHLIGHT, fcolor);
		 VertType = 0;
	 }
	 else
	 {
		 // otherwise, find normal stored material
		 if (&Material == NULL)
			 mi = FindMatIndex(BMAT_NAME_PLAIN, fcolor);
		 else
			 mi = FindMatIndex(Material, fcolor);
		 VertType = VT_Normals | VT_TexCoords;
	 }

	 int i, size = m_Mesh.GetSize();
	 for (i = 0; i < size; i++)
	 {
		 if (m_Mesh[i].m_iMatIdx == mi && m_Mesh[i].m_ePrimType == ePrimType)
			 return m_Mesh[i].m_pMesh;
	 }
	 // didn't find it, so we need to make it
	 MatMesh mm;
	 mm.m_iMatIdx = mi;
	 mm.m_ePrimType = ePrimType;

	 // Potential Optimization: should calculate how many vertices the building
	 // will take.  Even the simplest building will use 20 vertices, for now
	 // just use 40 as a reasonable starting point for each mesh.

	 mm.m_pMesh = new vtMesh(ePrimType, VertType, 40);
	 m_Mesh.Append(mm);
	 return mm.m_pMesh;
}

//
// Edges are created from a series of features ("panels", "sections")
//
void vtBuilding3d::CreateEdgeGeometry(vtLevel *pLev, const FPolygon3 &polygon1,
									   const FPolygon3 &polygon2, int iEdge, bool bShowEdge)
{
	 // Get edge from complete list
	 vtEdge *pEdge = pLev->GetEdge(iEdge);

	 // Then determine which ring its on
	 int ring = polygon1.WhichRing(iEdge);
	 const FLine3 &poly1 = polygon1[ring];
	 const FLine3 &poly2 = polygon2[ring];

	 // number of edges in this ring
	 int num_edges = poly1.GetSize();
	 int i = iEdge, j = (i+1)%num_edges;

	 FLine3 quad(4);

	 // start with the whole wall section
	 quad[0] = poly1[i];
	 quad[1] = poly1[j];
	 quad[2] = poly2[i];
	 quad[3] = poly2[j];

	 // length of the edge
	 FPoint3 dir1 = quad[1] - quad[0];
	 FPoint3 dir2 = quad[3] - quad[2];
	 float total_length1 = dir1.Length();
	 float total_length2 = dir2.Length();
	 if (total_length1 > 0.0f)
		 dir1.Normalize();
	 if (total_length2 > 0.0f)
		 dir2.Normalize();

	 if (bShowEdge)
	 {
		 AddHighlightSection(pEdge, quad);
	 }

	 // How wide should each feature be?
	 // Determine how much space we have for the proportional features after
	 // accounting for the fixed-width features
	 float fixed_width = pEdge->FixedFeaturesWidth();
	 float total_prop = pEdge->ProportionTotal();
	 float dyn_width = total_length1 - fixed_width;

	 if (pEdge->m_Facade != "")
	 {
		 // If we can successfully construct the facade, we don't need to
		 //  use the edge features.
		 if (MakeFacade(pEdge, quad, 1))
			 return;
	 }

	 // build the edge features.
	 // point[0] is the first starting point of a panel.
	 for (i = 0; i < pEdge->NumFeatures(); i++)
	 {
		 vtEdgeFeature &feat = pEdge->m_Features[i];

		 // determine real width
		 float meter_width = 0.0f;
		 if (feat.m_width >= 0)
			 meter_width = feat.m_width;
		 else
			 meter_width = (feat.m_width / total_prop) * dyn_width;
		 quad[1] = quad[0] + dir1 * meter_width;
		 quad[3] = quad[2] + dir2 * (meter_width * total_length2 / total_length1);

		 if (feat.m_code == WFC_WALL)
		 {
			 AddWallNormal(pEdge, &feat, quad);
		 }
		 if (feat.m_code == WFC_GAP)
		 {
			 // do nothing
		 }
		 if (feat.m_code == WFC_POST)
		 {
			 // TODO
		 }
		 if (feat.m_code == WFC_WINDOW)
		 {
			 AddWindowSection(pEdge, &feat, quad);
		 }
		 if (feat.m_code == WFC_DOOR)
		 {
			 AddDoorSection(pEdge, &feat, quad);
		 }
		 quad[0] = quad[1];
		 quad[2] = quad[3];
	 }
}

/**
  * Creates geometry for a highlighted area (an edge).
  */
void vtBuilding3d::AddHighlightSection(vtEdge *pEdge,
	 const FLine3 &quad)
{
	 // determine 4 points at corners of wall section
	 FPoint3 p0 = quad[0];
	 FPoint3 p1 = quad[1];
	 FPoint3 p3 = quad[2];
	 FPoint3 p2 = quad[3];

	 vtMesh *mesh = FindMatMesh(BMAT_NAME_PLAIN, RGBi(255,255,255),
vtMesh::LINE_STRIP);

	 // determine normal (not used for shading)
	 FPoint3 norm = Normal(p0,p1,p2);

	 int start =
		 mesh->AddVertex(p0 + norm);
	 mesh->AddVertex(p1 + norm);
	 mesh->AddVertex(p2 + norm);
	 mesh->AddVertex(p3 + norm);
	 mesh->AddVertex(p0 + norm);
	 mesh->AddFan(start, start+1, start+2, start+3, start+4);

	 start = mesh->AddVertex(p0);
	 mesh->AddVertex(p0 + norm);
	 mesh->AddFan(start, start+1);

	 start = mesh->AddVertex(p1);
	 mesh->AddVertex(p1 + norm);
	 mesh->AddFan(start, start+1);

	 start = mesh->AddVertex(p2);
	 mesh->AddVertex(p2 + norm);
	 mesh->AddFan(start, start+1);

	 start = mesh->AddVertex(p3);
	 mesh->AddVertex(p3 + norm);
	 mesh->AddFan(start, start+1);

	 norm *= 0.95f;
	 mesh = FindMatMesh(BMAT_NAME_PLAIN, RGBi(255,0,0), vtMesh::LINE_STRIP);
	 start =
		 mesh->AddVertex(p0 + norm);
	 mesh->AddVertex(p1 + norm);
	 mesh->AddVertex(p2 + norm);
	 mesh->AddVertex(p3 + norm);
	 mesh->AddVertex(p0 + norm);
	 mesh->AddFan(start, start+1, start+2, start+3, start+4);
}

/**
  * Builds a wall, given material index, starting and end points, height, and
  * starting height.
  */
void vtBuilding3d::AddWallSection(vtEdge *pEdge, bool bUniform,
	 const FLine3 &quad, float vf1, float vf2, float hf1)
{
	 // determine 4 points at corners of wall section
	 FPoint3 up1 = (quad[2] - quad[0]);
	 FPoint3 up2 = (quad[3] - quad[1]);
	 FPoint3 p0 = quad[0] + (up1 * vf1);
	 FPoint3 p1 = quad[1] + (up2 * vf1);
	 FPoint3 p3 = quad[0] + (up1 * vf2);
	 FPoint3 p2 = quad[1] + (up2 * vf2);

	 vtMesh *mesh;
	 if (bUniform)
		 mesh = FindMatMesh(BMAT_NAME_WINDOWWALL, pEdge->m_Color,
vtMesh::TRIANGLE_FAN);
	 else
		 mesh = FindMatMesh(*pEdge->m_pMaterial, pEdge->m_Color, vtMesh::TRIANGLE_FAN);

	 // determine normal and primary axes of the face
	 FPoint3 norm = Normal(p0, p1, p2);
	 FPoint3 axis0, axis1;
	 axis0 = p1 - p0;
	 axis0.Normalize();
	 axis1 = norm.Cross(axis0);

	 // determine UVs - special case for window-wall texture
	 FPoint2 uv0, uv1, uv2, uv3;
	 if (bUniform)
	 {
		 uv0.Set(0, 0);
		 uv1.Set(hf1, 0);
		 uv2.Set(hf1, vf2);
		 uv3.Set(0, vf2);
	 }
	 else
	 {
		 float u1 = (p1 - p0).Dot(axis0);
		 float u2 = (p2 - p0).Dot(axis0);
		 float u3 = (p3 - p0).Dot(axis0);
		 float v2 = (p2 - p0).Dot(axis1);
		 vtMaterialDescriptor *md =
s_MaterialDescriptors.FindMaterialDescriptor(*pEdge->m_pMaterial,
pEdge->m_Color);
		 uv0.Set(0, 0);
		 uv1.Set(u1, 0);
		 uv2.Set(u2, v2);
		 uv3.Set(u3, v2);
		 if (md != NULL)
		 {
			 // divide meters by [meters/uv] to get uv
			 FPoint2 UVScale = md->GetUVScale();
			 uv0.Div(UVScale);
			 uv1.Div(UVScale);
			 uv2.Div(UVScale);
			 uv3.Div(UVScale);
		 }
	 }

	 int start =
		 mesh->AddVertexNUV(p0, norm, uv0);
	 mesh->AddVertexNUV(p1, norm, uv1);
	 mesh->AddVertexNUV(p2, norm, uv2);
	 mesh->AddVertexNUV(p3, norm, uv3);

	 mesh->AddFan(start, start+1, start+2, start+3);
}

void vtBuilding3d::AddWallNormal(vtEdge *pEdge, vtEdgeFeature *pFeat,
	 const FLine3 &quad)
{
	 float vf1 = pFeat->m_vf1;
	 float vf2 = pFeat->m_vf2;
	 AddWallSection(pEdge, false, quad, vf1, vf2);
}

/**
  * Builds a door section.  will also build the wall above the door to ceiling
  * height.
  */
void vtBuilding3d::AddDoorSection(vtEdge *pEdge, vtEdgeFeature *pFeat,
	 const FLine3 &quad)
{
	 float vf1 = 0;
	 float vf2 = pFeat->m_vf2;

	 // determine 4 points at corners of section
	 FPoint3 up1 = (quad[2] - quad[0]);
	 FPoint3 up2 = (quad[3] - quad[1]);
	 FPoint3 p0 = quad[0] + (up1 * vf1);
	 FPoint3 p1 = quad[1] + (up2 * vf1);
	 FPoint3 p3 = quad[0] + (up1 * vf2);
	 FPoint3 p2 = quad[1] + (up2 * vf2);

	 vtMesh *mesh = FindMatMesh(BMAT_NAME_DOOR, pEdge->m_Color,
vtMesh::TRIANGLE_FAN);

	 // determine normal (flat shading, all vertices have the same normal)
	 FPoint3 norm = Normal(p0, p1, p2);

	 int start =
		 mesh->AddVertexNUV(p0, norm, FPoint2(0.0f, 0.0f));
	 mesh->AddVertexNUV(p1, norm, FPoint2(1.0f, 0.0f));
	 mesh->AddVertexNUV(p2, norm, FPoint2(1.0f, 1.0f));
	 mesh->AddVertexNUV(p3, norm, FPoint2(0.0f, 1.0f));

	 mesh->AddFan(start, start+1, start+2, start+3);

	 //add wall above door
	 AddWallSection(pEdge, false, quad, vf2, 1.0f);
}

//builds a window section.  builds the wall below and above a window too.
void vtBuilding3d::AddWindowSection(vtEdge *pEdge, vtEdgeFeature *pFeat,
	 const FLine3 &quad)
{
	 float vf1 = pFeat->m_vf1;
	 float vf2 = pFeat->m_vf2;

	 // build wall to base of window.
	 AddWallSection(pEdge, false, quad, 0, vf1);

	 // build wall above window
	 AddWallSection(pEdge, false, quad, vf2, 1.0f);

	 // determine 4 points at corners of section
	 FPoint3 up1 = (quad[2] - quad[0]);
	 FPoint3 up2 = (quad[3] - quad[1]);
	 FPoint3 p0 = quad[0] + (up1 * vf1);
	 FPoint3 p1 = quad[1] + (up2 * vf1);
	 FPoint3 p3 = quad[0] + (up1 * vf2);
	 FPoint3 p2 = quad[1] + (up2 * vf2);

	 vtMesh *mesh = FindMatMesh(BMAT_NAME_WINDOW, pEdge->m_Color,
vtMesh::TRIANGLE_FAN);

	 // determine normal (flat shading, all vertices have the same normal)
	 FPoint3 norm = Normal(p0,p1,p2);

	 int start =
		 mesh->AddVertexNUV(p0, norm, FPoint2(0.0f, 0.0f));
	 mesh->AddVertexNUV(p1, norm, FPoint2(1.0f, 0.0f));
	 mesh->AddVertexNUV(p2, norm, FPoint2(1.0f, 1.0f));
	 mesh->AddVertexNUV(p3, norm, FPoint2(0.0f, 1.0f));

	 mesh->AddFan(start, start+1, start+2, start+3);
}


void vtBuilding3d::AddFlatRoof(const FPolygon3 &pp, vtLevel *pLev)
{
	 FPoint3 up(0.0f, 1.0f, 0.0f); // vector pointing up
	 int rings = pp.size();
	 int outer_corners = pp[0].GetSize();
	 int i, j;
	 FPoint2 uv;

	 vtEdge *pEdge = pLev->GetEdge(0);
	 const vtString& Material = *pEdge->m_pMaterial;
	 vtMesh *mesh = FindMatMesh(Material, pEdge->m_Color, vtMesh::TRIANGLES);
	 vtMaterialDescriptor *md =
s_MaterialDescriptors.FindMaterialDescriptor(Material, pEdge->m_Color);

	 if (outer_corners > 4 || rings > 1)
	 {
		 // roof consists of a polygon which must be split into triangles
		 //  Invoke the triangulator to triangulate this polygon.
#if 1
		 // Use 'Triangle'
		 const FLine3 &outer = pp[0];
		 float roof_y = outer[0].y;
		 DPolygon2 foot2d;
		 ProjectionXZ(pp, foot2d);

		 // Triangle has been known to behave poorly with redundant vertices
		 //  We are in meters now, so we can use a centimeter epsilon.
		 int removed = foot2d.RemoveDegeneratePoints(0.08);
		 if (removed)
			 VTLOG("Skipped %d redundant vertices.\n", removed);

		 // a polyline to hold the answer in sets of three points
		 DLine2 result2d;
		 CallTriangle(foot2d, result2d);

		 FLine3 result;
		 ProjectionXZ(result2d, roof_y, result);
#else
		 // Use older, simpler triangulator
		 FLine3 outer = pp[0];
		 FLine2 roof;
		 roof.SetMaxSize(outer_corners);
		 for (i = 0; i < outer_corners; i++)
			 roof.Append(FPoint2(outer[i].x, outer[i].z));
		 float roof_y = outer[0].y;
		 FLine2 result;
		 Triangulate_f::Process(roof, result);
#endif

		 // use the results.
		 int tcount = result.GetSize()/3;
		 int ind[3];
		 FPoint2 gp;
		 FPoint3 p;

		 for (i=0; i<tcount; i++)
		 {
			 for (j = 0; j < 3; j++)
			 {
				 p = result[i*3+j];
				 uv.Set(p.x, p.z);
				 if (md)
					 uv.Div(md->GetUVScale()); // divide meters by [meters/uv] to get uv
				 ind[j] = mesh->AddVertexNUV(p, up, uv);
			 }
			 mesh->AddTri(ind[0], ind[1], ind[2]);
		 }
	 }
	 else
	 {
		 int idx[MAX_WALLS];
		 for (i = 0; i < outer_corners; i++)
		 {
			 FPoint3 p = pp[0][i];
			 uv.Set(p.x, p.z);
			 if (md)
				 uv.Div(md->GetUVScale()); // divide meters by [meters/uv] to get uv
			 idx[i] = mesh->AddVertexNUV(p, up, uv);
		 }
		 if (outer_corners > 2)
			 mesh->AddTri(idx[0], idx[1], idx[2]);
		 if (outer_corners > 3)
			 mesh->AddTri(idx[2], idx[3], idx[0]);
	 }
}


float vtBuilding3d::MakeFelkelRoof(const FPolygon3 &EavePolygons, vtLevel *pLev)
{
	 vtStraightSkeleton StraightSkeleton;
	 CSkeleton Skeleton;
	 float fMaxHeight = 0.0;
	 ContourVector RoofEaves(EavePolygons.size());
	 int i;
	 CSkeletonLine *pStartEdge;
	 CSkeletonLine *pEdge;
	 CSkeletonLine *pNextEdge;
	 bool bEdgeReversed;
	 float EaveY = EavePolygons[0][0].y;
#ifdef FELKELDEBUG
	 float DebugX;
	 float DebugY;
	 float DebugZ;
#endif

	 // Make a roof using felkels straight skeleton algorithm

	 // First of all build the eave footprint.
	 ContourVector::iterator itV = RoofEaves.begin();
	 for (FPolygon3::const_iterator itP = EavePolygons.begin(); itP !=
EavePolygons.end(); itP++, itV++)
	 {
		 int iVertices = (*itP).GetSize();
		 for (i = 0; i < iVertices; i++)
		 {
			 FPoint3 CurrentPoint = (*itP)[i];
			 FPoint3 NextPoint = (*itP)[(i+1)%iVertices];
			 FPoint3 PreviousPoint = (*itP)[(iVertices+i-1)%iVertices];
			 int iSlope = pLev->GetEdge(i)->m_iSlope;
			 if (iSlope > 89)
				 iSlope = 90;
			 else if (iSlope < 1)
				 iSlope = 0;
			 int iPrevSlope = pLev->GetEdge((iVertices+i-1)%iVertices)->m_iSlope;
			 if (iPrevSlope > 89)
				 iPrevSlope = 90;
			 else if (iPrevSlope < 1)
				 iPrevSlope = 0;
			 // If edges are in line and slopes are different then
			 if ((iPrevSlope != iSlope)
				 && Collinear2d(PreviousPoint, CurrentPoint, NextPoint))
			 {
#ifdef FELKELDEBUG
				 VTLOG("Adding dummy eave segment at %d\n", i);
#endif
				 // Duplicate the current edge vector
				 FPoint3 OldEdge = NextPoint - CurrentPoint;
				 FPoint3 NewEdge;
				 int iNewSlope;
				 if (iSlope > iPrevSlope)
				 {
					 // Rotate new vertex inwards (clockwise)
					 NewEdge.x = OldEdge.z;
					 NewEdge.z = -OldEdge.x;
					 iNewSlope = iPrevSlope;
				 }
				 else
				 {
					 // Rotate new vertext outwards (anticlockwise)
					 NewEdge.x = -OldEdge.z;
					 NewEdge.z = OldEdge.x;
					 iNewSlope = iSlope;
				 }
				 // Scale to .01 of a co-ord unit
				 NewEdge.Normalize();
				 NewEdge = NewEdge/100.0f;
				 NewEdge += CurrentPoint;
				 (*itV).push_back(CEdge(NewEdge.x, 0, NewEdge.z,
					 iNewSlope / 180.0f * PIf, pLev->GetEdge(i)->m_pMaterial,
					 pLev->GetEdge(i)->m_Color));
			 }
			 (*itV).push_back(CEdge(CurrentPoint.x, 0, CurrentPoint.z,
				 iSlope / 180.0f * PIf, pLev->GetEdge(i)->m_pMaterial,
				 pLev->GetEdge(i)->m_Color));
		 }
	 }

	 // Now build the skeleton
	 StraightSkeleton.MakeSkeleton(RoofEaves);

	 if (0 == StraightSkeleton.m_skeleton.size())
		 return -1.0;

	 // Merge the original eaves back into the skeleton
	 Skeleton = StraightSkeleton.CompleteWingedEdgeStructure(RoofEaves);

	 if (0 == Skeleton.size())
		 return -1.0;

#ifdef FELKELDEBUG
	 VTLOG("Building Geometry\n");
#endif
	 // TODO - texture co-ordinates
	 // Build the geometry
	 for (size_t ci = 0; ci < RoofEaves.size(); ci++)
	 {
		 Contour& points = RoofEaves[ci];
		 for (size_t pi = 0; pi < points.size(); pi++)
		 {
			 // For each boundary edge zip round the polygon anticlockwise
			 // and build the vertex array
			 const vtString bmat = *points[pi].m_pMaterial;
			 vtMesh *pMesh = FindMatMesh(bmat, points[pi].m_Color, vtMesh::TRIANGLES);
			 vtMaterialDescriptor *pMd =
s_MaterialDescriptors.FindMaterialDescriptor(bmat, points[pi].m_Color);
			 FPoint2 UVScale;
			 if (NULL != pMd)
				 UVScale = pMd->GetUVScale();
			 else
				 UVScale = FPoint2(1.0, 1.0);
			 FLine3 RoofSection3D;
			 FLine3 TriangulatedRoofSection3D;
			 int iTriangleCount = 0;
			 FPoint3 PanelNormal;
			 FPoint3 UAxis;
			 FPoint3 VAxis;
			 FPoint3 TextureOrigin;
			 int i, j;
			 vtArray<int> iaVertices;

			 C3DPoint& p1 = points[pi].m_Point;
			 C3DPoint& p2 = points[(pi+1)%points.size()].m_Point;
			 // Find the starting edge
			 CSkeleton::iterator s1;
			 for (s1 = Skeleton.begin(); s1 != Skeleton.end(); s1++)
			 {
				 if (((*s1).m_lower.m_vertex->m_point == p1) &&
					 ((*s1).m_higher.m_vertex->m_point == p2))
					 break;
			 }
			 if (s1 == Skeleton.end())
				 break;

			 pStartEdge = &(*s1);
			 pEdge = pStartEdge;
			 bEdgeReversed = false;
#ifdef FELKELDEBUG
			 VTLOG("Building panel\n");
#endif
			 unsigned int iNumberofPoints = 0;
			 do
			 {
				 if (iNumberofPoints++ > Skeleton.size())
				 {
					 VTLOG("MakeFelkelRoof - Roof geometry too complex - giving up\n");
					 return -1.0;
				 }
				 if (bEdgeReversed)
				 {
#ifdef FELKELDEBUG
					 DebugX = pEdge->m_higher.m_vertex->m_point.m_x;
					 DebugY = pEdge->m_higher.m_vertex->m_point.m_y;
					 DebugZ = pEdge->m_higher.m_vertex->m_point.m_z;
#endif
					 if (pEdge->m_higher.m_vertex->m_point.m_z > (double)fMaxHeight)
						 fMaxHeight = (float) pEdge->m_higher.m_vertex->m_point.m_z;
					 RoofSection3D.Append(FPoint3(pEdge->m_higher.m_vertex->m_point.m_x,
pEdge->m_higher.m_vertex->m_point.m_y + EaveY,
pEdge->m_higher.m_vertex->m_point.m_z));
					 pNextEdge = pEdge->m_higher.m_right;
// 			 if (pEdge->m_higher.m_vertex->m_point !=
pNextEdge->m_higher.m_vertex->m_point)
					 if (pEdge->m_higher.VertexID() != pNextEdge->m_higher.VertexID())
						 bEdgeReversed = true;
					 else
						 bEdgeReversed = false;
				 }
				 else
				 {
#ifdef FELKELDEBUG
					 DebugX = pEdge->m_lower.m_vertex->m_point.m_x;
					 DebugY = pEdge->m_lower.m_vertex->m_point.m_y;
					 DebugZ = pEdge->m_lower.m_vertex->m_point.m_z;
#endif
					 if (pEdge->m_lower.m_vertex->m_point.m_z > (double)fMaxHeight)
						 fMaxHeight = (float) pEdge->m_lower.m_vertex->m_point.m_z;
					 RoofSection3D.Append(FPoint3(pEdge->m_lower.m_vertex->m_point.m_x,
pEdge->m_lower.m_vertex->m_point.m_y + EaveY,
pEdge->m_lower.m_vertex->m_point.m_z));
					 pNextEdge = pEdge->m_lower.m_right;
// 			 if (pEdge->m_lower.m_vertex->m_point !=
pNextEdge->m_higher.m_vertex->m_point)
					 if (pEdge->m_lower.VertexID() != pNextEdge->m_higher.VertexID())
						 bEdgeReversed = true;
					 else
						 bEdgeReversed = false;
				 }
#ifdef FELKELDEBUG
				 VTLOG("Adding point (ID %d) x %e y %e z %e\n", pEdge->m_ID, DebugX, DebugY,
DebugZ);
#endif
				 pEdge = pNextEdge;
			 }
			 // For some reason the pointers dont end up quite the same
			 // I will work it out someday
			 while (pEdge->m_ID != pStartEdge->m_ID);


			 // Remove any vertices that are the same
			 for (i = 0; i < (int)RoofSection3D.GetSize(); i++)
			 {
				 FPoint3& Point = RoofSection3D[i];

				 for (j = i + 1; j < (int)RoofSection3D.GetSize(); j++)
				 {
					 FPoint3& NextPoint = RoofSection3D[j];
					 if (NextPoint == Point)
					 {
						 RoofSection3D.RemoveAt(j);
						 j--;
					 }
				 }
			 }


			 // determine normal and primary axes of the face
			 j = RoofSection3D.GetSize();
			 PanelNormal = Normal(RoofSection3D[1], RoofSection3D[0], RoofSection3D[j-1]);
			 UAxis = FPoint3(RoofSection3D[j-1] - RoofSection3D[0]).Normalize();
			 VAxis = PanelNormal.Cross(UAxis);
			 TextureOrigin = RoofSection3D[0];
#ifdef FELKELDEBUG
			 VTLOG("Panel normal x %e y %e z %e\n", PanelNormal.x, PanelNormal.y,
PanelNormal.z);
#endif
			 // Build transform to rotate plane parallel to the xz plane.
			 // N.B. this only work with angles from the plane normal to the y axis
			 // in the rangle 0 to pi/2 (this is ok for roofs). If you want
			 // it to work over a greater range you will have to mess with the sign of the
cosine
			 // of this angle.
			 float fHypot = sqrtf(PanelNormal.x * PanelNormal.x + PanelNormal.z *
PanelNormal.z);
			 FMatrix3 Transform;
			 Transform.SetRow(0, PanelNormal.x * PanelNormal.y / fHypot, PanelNormal.x,
-PanelNormal.z / fHypot);
			 Transform.SetRow(1, -fHypot, PanelNormal.y, 0);
			 Transform.SetRow(2, PanelNormal.z * PanelNormal.y / fHypot, PanelNormal.z,
PanelNormal.x / fHypot);

			 // Build vertex list
			 for (i = 0; i < j; i++)
			 {
				 FPoint3 Vertex = RoofSection3D[i];
				 FPoint2 UV = FPoint2((Vertex - TextureOrigin).Dot(UAxis), (Vertex -
TextureOrigin).Dot(VAxis));
				 UV.Div(UVScale);
				 iaVertices.Append(pMesh->AddVertexNUV(Vertex, PanelNormal, UV));
			 }

			 for (i = 0; i < j; i++)
			 {
				 // Source and dest cannot be the same
				 FPoint3 Temp = RoofSection3D[i];
				 Transform.Transform(Temp, RoofSection3D[i]);
			 }

			 Triangulate_f::Process(RoofSection3D, TriangulatedRoofSection3D);
			 iTriangleCount = TriangulatedRoofSection3D.GetSize() / 3;

			 for (i = 0; i < iTriangleCount; i++)
			 {
				 int iaIndex[3];

				 for (j = 0; j < 3; j++)
				 {
					 FPoint3 Point = TriangulatedRoofSection3D[i * 3 + j];
					 if (-1 == (iaIndex[j] = FindVertex(Point, RoofSection3D, iaVertices)))
						 return -1.0;
				 }
				 pMesh->AddTri(iaIndex[0], iaIndex[2], iaIndex[1]);
#ifdef FELKELDEBUG
				 VTLOG("AddTri1 %d %d %d\n", iaIndex[0], iaIndex[2], iaIndex[1]);
#endif
			 }
		 }
	 }

	 return fMaxHeight;
}

bool vtBuilding3d::Collinear2d(const FPoint3& Previous, const FPoint3& Current,
const FPoint3& Next)
{
	 FPoint3 l1 = Previous - Current;
	 FPoint3 l2 = Next - Current;

	 l1.y = 0;
	 l2.y = 0;

	 l1.Normalize();
	 l2.Normalize();

	 float CosTheta = l1.Dot(l2);
	 if (CosTheta < -1.0)
		 CosTheta = -1.0;
	 else if (CosTheta > 1.0)
		 CosTheta = 1.0;
	 float fTheta = acosf(CosTheta) / PIf * 180;

	 if (fabs(fTheta - 180.0) < 1.0)
		 return true;
	 else
		 return false;
}

int vtBuilding3d::FindVertex(FPoint3 Point, FLine3 &RoofSection3D,
	 vtArray<int> &iaVertices)
{
	 int iSize = RoofSection3D.GetSize();

	 int i;
	 for (i = 0; i < iSize; i++)
	 {
		 if ((Point.x == RoofSection3D[i].x) &&
			 (Point.y == RoofSection3D[i].y) &&
			 (Point.z == RoofSection3D[i].z))
			 break;
	 }
	 if (i < iSize)
		 return iaVertices[i];
	 else
	 {
		 VTLOG("FindVertex - vertex not found\n");
		 return -1;
	 }
}

//
// Walls which consist of regularly spaced windows and 'siding' material
// can be modelled far more efficiently.  This is very useful for rendering
// speed for large scenes in which the user doesn't have or doesn't care
// about the exact material/windows of the buildings.  We create
// optimized geometry in which each whole wall is a single quad.
//
void vtBuilding3d::CreateUniformLevel(int iLevel, float fHeight,
	 int iHighlightEdge)
{
	 vtLevel *pLev = m_Levels[iLevel];

	 const FPolygon3 &polygon1 = GetLocalFootprint(iLevel);

	 int i;
	 int base_edge = 0;
	 for (unsigned int ring = 0; ring < polygon1.size(); ring++)
	 {
		 FLine3 poly1 = polygon1[ring];
		 FLine3 poly2;

		 int edges = poly1.GetSize();
		 for (i = 0; i < edges; i++)
			 poly1[i].y = fHeight;

		 poly2 = poly1;
		 for (i = 0; i < edges; i++)
			 poly2[i].y += pLev->m_fStoryHeight;

		 for (i = 0; i < edges; i++)
		 {
			 int a = i, b = (a+1)%edges;

			 FLine3 quad(4);

			 vtEdge *pEdge = pLev->GetEdge(base_edge+i);

			 // do the whole wall section
			 quad[0] = poly1[a];
			 quad[1] = poly1[b];
			 quad[2] = poly2[a];
			 quad[3] = poly2[b];

			 if (pEdge->m_Facade != "")
			 {
				 float extraheight = pLev->m_fStoryHeight * (pLev->m_iStories-1);
				 quad[2].y += extraheight;
				 quad[3].y += extraheight;
				 // If we can successfully construct the facade, we don't need to
				 //  use the edge features.
				 if (MakeFacade(pEdge, quad, pLev->m_iStories))
					 continue;
			 }
			 quad[2] = poly2[a];
			 quad[3] = poly2[b];

			 float h1 = 0.0f;
			 float h2 = (float) pLev->m_iStories;
			 float hf1 = (float) pEdge->NumFeaturesOfCode(WFC_WINDOW);
			 AddWallSection(pEdge, true, quad, h1, h2, hf1);

			 if (base_edge+i == iHighlightEdge)
			 {
				 for (unsigned int j = 0; j < pLev->m_iStories; j++)
				 {
					 AddHighlightSection(pEdge, quad);
					 quad[0].y += pLev->m_fStoryHeight;
					 quad[1].y += pLev->m_fStoryHeight;
					 quad[2].y += pLev->m_fStoryHeight;
					 quad[3].y += pLev->m_fStoryHeight;
				 }
			 }
		 }
		 base_edge += edges;
	 }
}

bool vtBuilding3d::MakeFacade(vtEdge *pEdge, FLine3 &quad, int stories)
{
	 // Paint a facade on this edge
	 // Add the facade image to the materials array
	 // Assume quad is ordered 0,1,3,2
	 MatMesh mm;
	 FPoint3 norm = Normal(quad[0],quad[1],quad[3]);

	 vtString fname = "Facade/";
	 fname += pEdge->m_Facade;
	 fname = FindFileOnPaths(vtGetDataPath(), (pcchar)fname);
	 if (fname == "")
	 {
		 // Older files may have their facades in 'BuildingModels'
		 fname = "BuildingModels/";
		 fname += pEdge->m_Facade;
		 fname = FindFileOnPaths(vtGetDataPath(), (pcchar)fname);
	 }
	 if (fname == "")
	 {
		 VTLOG(" Couldn't find facade texture '%s'\n", (const char*)pEdge->m_Facade);
		 return false;
	 }

	 mm.m_iMatIdx = GetSharedMaterialArray()->AddTextureMaterial2(fname,
			 true, true, false, false,
			 TERRAIN_AMBIENT,
			 TERRAIN_DIFFUSE,
			 1.0f,  // alpha
			 TERRAIN_EMISSIVE);

	 // Create a mesh for the new material and add this to the mesh array
	 mm.m_pMesh = new vtMesh(vtMesh::TRIANGLE_FAN, VT_Normals | VT_TexCoords, 6);
	 m_Mesh.Append(mm);

	 // Calculate the vertices and add them to the mesh
	 float v = (float) stories;
	 int start = mm.m_pMesh->AddVertexNUV(quad[0], norm, FPoint2(0.0f, 0.0f));
	 mm.m_pMesh->AddVertexNUV(quad[1], norm, FPoint2(1.0f, 0.0f));
	 mm.m_pMesh->AddVertexNUV(quad[3], norm, FPoint2(1.0f, v));
	 mm.m_pMesh->AddVertexNUV(quad[2], norm,  FPoint2(0.0f, v));

	 mm.m_pMesh->AddFan(start, start+1, start+2, start+3);
	 return true;
}

FPoint3 vtBuilding3d::Normal(const FPoint3 &p0, const FPoint3 &p1, const FPoint3
&p2)
{
	 FPoint3 a = p0 - p1;
	 FPoint3 b = p2 - p1;
	 FPoint3 norm = b.Cross(a);
	 norm.Normalize();
	 return norm;
}

//
// Randomize buildings characteristics
//
void vtBuilding3d::Randomize(int iStories)
{
	 RGBi color;

	 color = GetColor(BLD_BASIC);
	 if (color.r == -1 && color.g == -1 && color.b == -1)
	 {
		 // unset color
		 // random pastel color
		 unsigned char r, g, b;
		 r = (unsigned char) (128 + random(127));
		 g = (unsigned char) (128 + random(127));
		 b = (unsigned char) (128 + random(127));
		 SetColor(BLD_BASIC, RGBi(r, g, b));
	 }

	 color = GetColor(BLD_ROOF);
	 if (color.r == -1 && color.g == -1 && color.b == -1)
	 {
		 // unset color
		 // random roof color
		 int r = rand() %5;
		 switch (r) {
			 case 0: color.Set(255, 255, 250); break; //off-white
			 case 1: color.Set(153, 51, 51); break;  //reddish
			 case 2: color.Set(153, 153, 255); break; //blue-ish
			 case 3: color.Set(153, 255, 153); break; //green-ish
			 case 4: color.Set(178, 102, 51); break;  //brown
		 }

		 SetColor(BLD_ROOF, color);
	 }
}


/**
  * Creates the geometry for the building.
  * Capable of several levels of detail (defaults to full detail).
  * If the geometry was already built previously, it is destroyed and re-created.
  *
  * \param pTerr The terrain on which to plant the building.
  */
bool vtBuilding3d::CreateNode(vtTerrain *pTerr)
{
	 if (m_pContainer)
	 {
		 // was build before; re-build geometry
		 DestroyGeometry();
	 }
	 else
	 {
		 // constructing for the first time
		 m_pContainer = new vtTransform;
		 m_pContainer->SetName2("building container");
	 }
	 if (!CreateGeometry(pTerr->GetHeightField()))
		 return false;
	 m_pContainer->AddChild(m_pGeom);
	 m_pContainer->SetTrans(m_center);
	 return true;
}

bool vtBuilding3d::IsCreated()
{
	 return (m_pContainer != NULL);
}

void vtBuilding3d::DeleteNode()
{
	 if (m_pContainer)
	 {
		 DestroyGeometry();
		 m_pContainer->Release();
		 m_pContainer = NULL;
	 }
}

/**
  * Display some bounding wires around the object to highlight it.
  */
void vtBuilding3d::ShowBounds(bool bShow)
{
	 if (bShow)
	 {
		 if (!m_pHighlight)
		 {
			 // the highlight geometry doesn't exist, so create it
			 // get bounding sphere
			 FSphere sphere;
			 m_pGeom->GetBoundSphere(sphere);

			 m_pHighlight = CreateBoundSphereGeom(sphere);
			 m_pContainer->AddChild(m_pHighlight);
		 }
		 m_pHighlight->SetEnabled(true);
	 }
	 else
	 {
		 if (m_pHighlight)
			 m_pHighlight->SetEnabled(false);
	 }
}

   ----------

//
// FelkelIntersection.cpp: implementation of the CIntersection class.
//
// Copyright (c) 2003-2006 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//
// Straight skeleton algorithm and original implementation
// courtesy of Petr Felkel and Stepan Obdrzalek (petr.felkel@...)
// Re-implemented for the Virtual Terrain Project (vterrain.org)
// by Roger James (www.beardandsandals.co.uk)
//


#include "FelkelIntersection.h"

#ifndef DOXYGEN_SHOULD_SKIP_THIS

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CIntersection :: CIntersection (CVertexList &vl, CVertex &v)
{
#if VTDEBUG
	 if (!(v.m_prevVertex == NULL || v.m_leftLine.FacingTowards (v.m_prevVertex ->
m_rightLine)))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
	 if (!(v.m_nextVertex == NULL || v.m_rightLine.FacingTowards (v.m_nextVertex ->
m_leftLine)))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
#endif

	 CVertex &l = *v.m_prevVertex;
	 CVertex &r = *v.m_nextVertex;

#if VTDEBUG
	 if (!(v.m_leftLine.m_Angle == v.m_leftVertex -> m_leftLine.m_Angle))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
	 if (!(v.m_rightLine.m_Angle == v.m_rightVertex -> m_rightLine.m_Angle))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
#endif

	 CNumber al = v.m_axis.m_Angle - l.m_axis.m_Angle;
	 al.NormalizeAngle();

	 CNumber ar = v.m_axis.m_Angle - r.m_axis.m_Angle;
	 ar.NormalizeAngle();

#ifdef FELKELDEBUG
	 VTLOG("New Intersection i1\n");
#endif
	 C3DPoint i1 = v.m_axis.FacingTowards(l.m_axis) ? C3DPoint(CN_INFINITY,
CN_INFINITY, CN_INFINITY) : v.m_axis.Intersection(l.m_axis);
	 i1.m_y = v.m_leftLine.Dist(i1) * fabs(tan(v.m_leftLine.m_Slope));
#ifdef FELKELDEBUG
	 VTLOG("New Intersection i1\nm_Origin(x %e y %e z %e) m_Angle %e m_Slope
%e\na.m_Origin(x %e y %e z %e) a.m_Angle %e a.m_Slope %e\n",
		 v.m_axis.m_Origin.m_x, v.m_axis.m_Origin.m_y, v.m_axis.m_Origin.m_z,
v.m_axis.m_Angle, v.m_axis.m_Slope,
		 l.m_axis.m_Origin.m_x, l.m_axis.m_Origin.m_y, l.m_axis.m_Origin.m_z,
l.m_axis.m_Angle, l.m_axis.m_Slope);
#endif
#ifdef FELKELDEBUG
	 VTLOG("New Intersection i2\n");
#endif
	 C3DPoint i2 = v.m_axis.FacingTowards (r.m_axis) ? C3DPoint(CN_INFINITY,
CN_INFINITY, CN_INFINITY) : v.m_axis.Intersection(r.m_axis);
	 i2.m_y = v.m_rightLine.Dist(i2) * fabs(tan(v.m_rightLine.m_Slope));
#ifdef FELKELDEBUG
	 VTLOG("m_Origin(x %e y %e z %e) m_Angle %e m_Slope %e\na.m_Origin(x %e y %e z
%e) a.m_Angle %e a.m_Slope %e\n",
		 v.m_axis.m_Origin.m_x, v.m_axis.m_Origin.m_y, v.m_axis.m_Origin.m_z,
v.m_axis.m_Angle, v.m_axis.m_Slope,
		 r.m_axis.m_Origin.m_x, r.m_axis.m_Origin.m_y, r.m_axis.m_Origin.m_z,
r.m_axis.m_Angle, r.m_axis.m_Slope);
#endif

#if VTDEBUG
	 CNumber Oldi1y = i1.m_y;
	 CNumber Oldi2y = i2.m_y;
#endif
	 // I need to check why this code is here !!!!!!!!!
	 // I must of put it here bu I cannot remember why
	 // Getting a slope of exactly PI/2 must be rare
	 // but could arise from many different edge slopes and vertex angles
	 if (SIMILAR(v.m_axis.m_Slope, CN_PI/2))
	 {
		 i1.m_y = C3DPoint(i1 - l.m_point).LengthXZ() * fabs(tan(l.m_axis.m_Slope)) +
l.m_point.m_y;
		 i2.m_y = C3DPoint(i2 - r.m_point).LengthXZ() * fabs(tan(r.m_axis.m_Slope)) +
r.m_point.m_y;
	 }
	 else
	 {
		 i1.m_y = C3DPoint(i1 - v.m_point).LengthXZ() * fabs(tan(v.m_axis.m_Slope)) +
v.m_point.m_y;
		 i2.m_y = C3DPoint(i2 - v.m_point).LengthXZ() * fabs(tan(v.m_axis.m_Slope)) +
v.m_point.m_y;
	 }
// assert ((Oldi1y == i1.m_y) && (Oldi2y == i2.m_y));

	 CNumber d1 = v.m_point.DistXZ(i1);
	 CNumber d2 = v.m_point.DistXZ(i2);
// CNumber d1 = i1.m_y;
// CNumber d2 = i2.m_y;


	 CVertex *leftPointer, *rightPointer;
	 C3DPoint p;
	 CNumber d3 = CN_INFINITY;
	 CNumber av = v.m_leftLine.m_Angle - v.m_rightLine.m_Angle;

	 av.NormalizeAngle();
	 if ((av >= 0.0 || av == - CN_PI) && (v.m_leftLine.Intersection(v.m_rightLine)
== v.m_point || v.m_leftLine.Intersection(v.m_rightLine) ==
C3DPoint(CN_INFINITY, CN_INFINITY, CN_INFINITY)))
		 d3 = v.NearestIntersection(vl, &leftPointer, &rightPointer, p);
// d3 = p.m_y;

#ifdef FELKELDEBUG
	 VTLOG("New Intersection i1\nm_Origin(x %e y %e z %e) m_Angle %e m_Slope
%e\na.m_Origin(x %e y %e z %e) a.m_Angle %e a.m_Slope %e\n",
		 v.m_axis.m_Origin.m_x, v.m_axis.m_Origin.m_y, v.m_axis.m_Origin.m_z,
v.m_axis.m_Angle, v.m_axis.m_Slope,
		 l.m_axis.m_Origin.m_x, l.m_axis.m_Origin.m_y, l.m_axis.m_Origin.m_z,
l.m_axis.m_Angle, l.m_axis.m_Slope);
	 VTLOG("New Intersection i2\nm_Origin(x %e y %e z %e) m_Angle %e m_Slope
%e\na.m_Origin(x %e y %e z %e) a.m_Angle %e a.m_Slope %e\n",
		 v.m_axis.m_Origin.m_x, v.m_axis.m_Origin.m_y, v.m_axis.m_Origin.m_z,
v.m_axis.m_Angle, v.m_axis.m_Slope,
		 r.m_axis.m_Origin.m_x, r.m_axis.m_Origin.m_y, r.m_axis.m_Origin.m_z,
r.m_axis.m_Angle, r.m_axis.m_Slope);
	 VTLOG("New Intersection\n al %e ar %e\ni1.x %e i1.y %e i1.z %e\ni2.x %e i2.y %e
i2.z %e\np.m_x %e p.m_y %e p.m_z %e\nd1 %e d2 %e d3 %e\n",
		 al, ar, i1.m_x, i1.m_y, i1.m_z, i2.m_x, i2.m_y, i2.m_z, p.m_x, p.m_y, p.m_z,
d1, d2, d3);
#endif

	 if (d3 <= d1 && d3 <= d2)
	 {
		 m_poi = p;
		 m_leftVertex = m_rightVertex = &v;
		 m_type = NONCONVEX;
		 if (v.InvalidIntersection (vl, *this))
		 {
			 d3 = CN_INFINITY;
			 m_poi == C3DPoint (CN_INFINITY, CN_INFINITY, CN_INFINITY);
		 }
	 }

	 if (d1 <= d2 && d1 <= d3)
	 {
		 m_leftVertex = &l;
		 m_rightVertex = &v;
		 m_poi = i1;
		 m_type = CONVEX;
	 }
	 else if (d2 <= d1 && d2 <= d3)
	 {
		 m_leftVertex = &v;
		 m_rightVertex = &r;
		 m_poi = i2;
		 m_type = CONVEX;
	 }

	 if (m_poi == C3DPoint (CN_INFINITY, CN_INFINITY, CN_INFINITY))
		 m_height = CN_INFINITY;
	 else
		 m_height = m_poi.m_y;

#ifdef FELKELDEBUG
	 VTLOG("New %s Intersection %d %d x %e y %e z %e height %e\n",
		 m_type == CONVEX ? "CONVEX" : "NONCONVEX",
		 m_leftVertex->m_ID, m_rightVertex->m_ID, m_poi.m_x, m_poi.m_y, m_poi.m_z,
m_height);
#endif
}

void CIntersection::ApplyNonconvexIntersection(CSkeleton &skeleton, CVertexList
&vl, IntersectionQueue &iq, bool bCheckVertexinCurrentContour)
{
#ifdef FELKELDEBUG
	 VTLOG("ApplyNonconvexIntersection\n");
#endif

#if VTDEBUG
	 // Left and right vertices must always be the same point
	 if (!(m_leftVertex == m_rightVertex))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
	 // Check to see of they are the same data structure RFJ !!!
	 if (!(m_leftVertex->m_ID == m_rightVertex->m_ID))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
#endif

	 CVertex *leftPointer, *rightPointer;
	 C3DPoint p;
	 CNumber d3 = CN_INFINITY;

	 d3 = m_leftVertex->NearestIntersection(vl, &leftPointer, &rightPointer, p);
	 if (d3 == CN_INFINITY)
		 return;

	 if (p != m_poi)
		 return;

	 if (!m_leftVertex->VertexInCurrentContour(*leftPointer))
	 {
		 if (bCheckVertexinCurrentContour) // Temporary hack to disable checking in
multiple contour buildings !!!! NEEDS FIXING
			 return;
		 else
			 VTLOG("Vertex in current contour check failed - needs to be fixed - this
check is not valid if one (or both?) of the contours is clockwise\n");
	 }
// Left and right vertex are actually the same in this case
	 if (!m_rightVertex->VertexInCurrentContour(*rightPointer))
	 {
		 VTLOG("Vertex in current contour check failed - needs to be fixed - this check
is not valid if one (or both?) of the contours is clockwise\n");
		 if (bCheckVertexinCurrentContour) // Temporary hack to disable checking in
multiple contour buildings !!!! NEEDS FIXING
			 return;
		 else
			 VTLOG("Vertex in current contour check failed - needs to be fixed - this
check is not valid if one (or both?) of the contours is clockwise\n");
	 }

#ifdef FELKELDEBUG
	 VTLOG("left vertex %d left ptr %d right ptr %d right vertex %d\n",
		 m_leftVertex->m_ID,
		 leftPointer->m_ID,
		 rightPointer->m_ID,
		 m_rightVertex->m_ID);
#endif

	 // Treat as a split event
	 CVertex v1 (p, *rightPointer, *m_rightVertex);
	 CVertex v2 (p, *m_leftVertex, *leftPointer);

#if VTDEBUG
	 if (!(v1.m_point != C3DPoint(CN_INFINITY, CN_INFINITY, CN_INFINITY)))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
	 if (!(v2.m_point != C3DPoint(CN_INFINITY, CN_INFINITY, CN_INFINITY)))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
#endif

	 m_leftVertex->m_done = true;
	 //  i.rightVertex -> done = true;

	 CVertex *newNext1 = m_rightVertex->m_nextVertex;
	 CVertex *newPrev1 = leftPointer->Highest();
	 v1.m_prevVertex = newPrev1;
	 v1.m_nextVertex = newNext1;
	 vl.push_back(v1);

	 CVertex *v1Pointer = &vl.back();

	 newPrev1->m_nextVertex = v1Pointer;
	 newNext1->m_prevVertex = v1Pointer;
	 m_rightVertex->m_higher = v1Pointer;

	 CVertex *newNext2 = rightPointer->Highest();
	 CVertex *newPrev2 = m_leftVertex->m_prevVertex;
	 v2.m_prevVertex = newPrev2;
	 v2.m_nextVertex = newNext2;
	 vl.push_back(v2);

	 CVertex *v2Pointer = &vl.back();

	 newPrev2->m_nextVertex = v2Pointer;
	 newNext2->m_prevVertex = v2Pointer;
	 m_leftVertex->m_higher = v2Pointer;

	 skeleton.push_back(CSkeletonLine(*m_rightVertex, *v1Pointer));

	 CSkeletonLine *linePtr = &skeleton.back();

	 skeleton.push_back(CSkeletonLine(*v1Pointer, *v2Pointer));

	 CSkeletonLine *auxLine1Ptr = &skeleton.back ();

	 skeleton.push_back(CSkeletonLine(*v2Pointer, *v1Pointer));

	 CSkeletonLine *auxLine2Ptr = &skeleton.back();

	 linePtr->m_lower.m_right = m_leftVertex->m_leftSkeletonLine;
	 linePtr->m_lower.m_left = m_leftVertex->m_rightSkeletonLine;

	 v1Pointer->m_rightSkeletonLine = v2Pointer->m_leftSkeletonLine = linePtr;
	 v1Pointer->m_leftSkeletonLine = auxLine1Ptr;
	 v2Pointer->m_rightSkeletonLine = auxLine2Ptr;

	 auxLine1Ptr->m_lower.m_right = auxLine2Ptr;
	 auxLine2Ptr->m_lower.m_left = auxLine1Ptr;

	 if (m_leftVertex->m_leftSkeletonLine)
		 m_leftVertex->m_leftSkeletonLine ->m_higher.m_left = linePtr;
	 if (m_leftVertex->m_rightSkeletonLine)
		 m_leftVertex->m_rightSkeletonLine->m_higher.m_right = linePtr;
	 m_leftVertex->m_advancingSkeletonLine = linePtr;

	 if (newNext1 == newPrev1)
	 {
		 v1Pointer->m_done = true;
		 newNext1->m_done = true;
		 skeleton.push_back(CSkeletonLine(*v1Pointer, *newNext1));
		 CSkeletonLine *linePtr = &skeleton.back();
		 linePtr->m_lower.m_right  = v1Pointer->m_leftSkeletonLine;
		 linePtr->m_lower.m_left   = v1Pointer->m_rightSkeletonLine;
		 linePtr->m_higher.m_right = newNext1->m_leftSkeletonLine;
		 linePtr->m_higher.m_left  = newNext1->m_rightSkeletonLine;

		 if (v1Pointer->m_leftSkeletonLine)
			 v1Pointer->m_leftSkeletonLine->m_higher.m_left  = linePtr;
		 if (v1Pointer->m_rightSkeletonLine)
			 v1Pointer->m_rightSkeletonLine->m_higher.m_right = linePtr;
		 if (newNext1->m_leftSkeletonLine)
			 newNext1->m_leftSkeletonLine->m_higher.m_left  = linePtr;
		 if (newNext1->m_rightSkeletonLine)
			 newNext1->m_rightSkeletonLine->m_higher.m_right = linePtr;
	 }
	 else
	 {
		 CIntersection i1(vl, *v1Pointer);
		 if (i1.m_height != CN_INFINITY)
			 iq.push (i1);
	 }

	 if (newNext2 == newPrev2)
	 {
		 v2Pointer->m_done = true;
		 newNext2 ->m_done = true;
		 skeleton.push_back(CSkeletonLine (*v2Pointer, *newNext2));
		 CSkeletonLine *linePtr = &skeleton.back();
		 linePtr->m_lower.m_right = v2Pointer->m_leftSkeletonLine;
		 linePtr->m_lower.m_left = v2Pointer->m_rightSkeletonLine;
		 linePtr->m_higher.m_right = newNext2->m_leftSkeletonLine;
		 linePtr->m_higher.m_left  = newNext2->m_rightSkeletonLine;

		 if (v2Pointer->m_leftSkeletonLine)
			 v2Pointer->m_leftSkeletonLine->m_higher.m_left  = linePtr;
		 if (v2Pointer->m_rightSkeletonLine)
			 v2Pointer->m_rightSkeletonLine->m_higher.m_right = linePtr;
		 if (newNext2->m_leftSkeletonLine)
			 newNext2 ->m_leftSkeletonLine->m_higher.m_left  = linePtr;
		 if (newNext2->m_rightSkeletonLine)
			 newNext2->m_rightSkeletonLine->m_higher.m_right = linePtr;
	 }
	 else
	 {
		 CIntersection i2 (vl, *v2Pointer);
		 if (i2.m_height != CN_INFINITY)
			 iq.push(i2);
	 }
}

void CIntersection::ApplyConvexIntersection(CSkeleton &skeleton, CVertexList
&vl, IntersectionQueue &iq)
{
#ifdef FELKELDEBUG
	 VTLOG("ApplyConvexIntersection\n");
#endif
	 // create new vertex and link into current contour
	 CVertex vtx (m_poi, *m_leftVertex, *m_rightVertex);
#if VTDEBUG
	 if(!(vtx.m_point != C3DPoint(CN_INFINITY, CN_INFINITY, CN_INFINITY)))
		 VTLOG("%s %d Assert failed\n", __FILE__, __LINE__);
#endif

	 // Link vertex into overall chain
	 CVertex *newNext = m_rightVertex->m_nextVertex;
	 CVertex *newPrev = m_leftVertex->m_prevVertex;

	 vtx.m_prevVertex = newPrev;
	 vtx.m_nextVertex = newNext;

	 vl.push_back (vtx);

	 CVertex *vtxPointer = &vl.back();

	 newPrev->m_nextVertex = vtxPointer;
	 newNext->m_prevVertex = vtxPointer;

	 // Set this vertex as the higher skeleton point for the vertices which have
been
	 // removed from the active contour
	 m_leftVertex->m_higher = vtxPointer;
	 m_rightVertex->m_higher = vtxPointer;

	 // mark vertices as inactive
	 m_leftVertex->m_done = true;
	 m_rightVertex->m_done = true;

	 CIntersection newI(vl, *vtxPointer);

	 if (newI.m_height != CN_INFINITY)
		 iq.push(newI);

	 skeleton.push_back(CSkeletonLine(*m_leftVertex, *vtxPointer));

	 CSkeletonLine *lLinePtr = &skeleton.back();

	 skeleton.push_back(CSkeletonLine (*m_rightVertex, *vtxPointer));

	 CSkeletonLine *rLinePtr = &skeleton.back();

	 lLinePtr->m_lower.m_right = m_leftVertex->m_leftSkeletonLine;
	 lLinePtr->m_lower.m_left = m_leftVertex->m_rightSkeletonLine;
	 lLinePtr->m_higher.m_right = rLinePtr;
	 rLinePtr->m_lower.m_right = m_rightVertex->m_leftSkeletonLine;
	 rLinePtr->m_lower.m_left = m_rightVertex->m_rightSkeletonLine;
	 rLinePtr->m_higher.m_left = lLinePtr;

	 if (m_leftVertex->m_leftSkeletonLine)
		 m_leftVertex->m_leftSkeletonLine->m_higher.m_left = lLinePtr;
	 if (m_leftVertex->m_rightSkeletonLine)
		 m_leftVertex->m_rightSkeletonLine->m_higher.m_right = lLinePtr;

	 if (m_rightVertex->m_leftSkeletonLine)
		 m_rightVertex->m_leftSkeletonLine->m_higher.m_left = rLinePtr;
	 if (m_rightVertex->m_rightSkeletonLine)
		 m_rightVertex->m_rightSkeletonLine->m_higher.m_right = rLinePtr;

	 vtxPointer->m_leftSkeletonLine = lLinePtr;
	 vtxPointer->m_rightSkeletonLine = rLinePtr;

	 m_leftVertex->m_advancingSkeletonLine = lLinePtr;
	 m_rightVertex->m_advancingSkeletonLine = rLinePtr;
}

void CIntersection::ApplyLast3(CSkeleton &skeleton, CVertexList &vl)
{
#ifdef FELKELDEBUG
	 VTLOG("ApplyLast3\n");
#endif

	 CVertex &v1 = *m_leftVertex;
	 CVertex &v2 = *m_rightVertex;
	 CVertex &v3 = *m_leftVertex->m_prevVertex;

	 v1.m_done = true;
	 v2.m_done = true;
	 v3.m_done = true;


	 C3DPoint is = m_poi;

	 CVertex v(is);

	 v.m_done = true;
	 vl.push_back(v);
	 CVertex *vtxPointer = &vl.back();

	 skeleton.push_back (CSkeletonLine(v1, *vtxPointer));

	 CSkeletonLine *line1Ptr = &skeleton.back();

	 skeleton.push_back (CSkeletonLine(v2, *vtxPointer));

	 CSkeletonLine *line2Ptr = &skeleton.back();

	 skeleton.push_back (CSkeletonLine(v3, *vtxPointer));

	 CSkeletonLine *line3Ptr = &skeleton.back ();

	 line1Ptr->m_higher.m_right = line2Ptr; // zapojeni okridlenych hran
	 line2Ptr->m_higher.m_right = line3Ptr;
	 line3Ptr->m_higher.m_right = line1Ptr;

	 line1Ptr->m_higher.m_left = line3Ptr;
	 line2Ptr ->m_higher.m_left = line1Ptr;
	 line3Ptr->m_higher.m_left = line2Ptr;

	 line1Ptr->m_lower.m_left = v1.m_rightSkeletonLine;
	 line1Ptr->m_lower.m_right = v1.m_leftSkeletonLine;

	 line2Ptr->m_lower.m_left = v2.m_rightSkeletonLine;
	 line2Ptr->m_lower.m_right = v2.m_leftSkeletonLine;

	 line3Ptr->m_lower.m_left = v3.m_rightSkeletonLine;
	 line3Ptr->m_lower.m_right = v3.m_leftSkeletonLine;

	 if (v1.m_leftSkeletonLine)
		 v1.m_leftSkeletonLine->m_higher.m_left = line1Ptr;
	 if (v1.m_rightSkeletonLine)
		 v1.m_rightSkeletonLine->m_higher.m_right = line1Ptr;

	 if (v2.m_leftSkeletonLine)
		 v2.m_leftSkeletonLine->m_higher.m_left = line2Ptr;
	 if (v2.m_rightSkeletonLine)
		 v2.m_rightSkeletonLine->m_higher.m_right = line2Ptr;

	 if (v3.m_leftSkeletonLine)
		 v3.m_leftSkeletonLine->m_higher.m_left = line3Ptr;
	 if (v3.m_rightSkeletonLine)
		 v3.m_rightSkeletonLine->m_higher.m_right = line3Ptr;

	 v1.m_advancingSkeletonLine = line1Ptr;
	 v2.m_advancingSkeletonLine = line2Ptr;
	 v3.m_advancingSkeletonLine = line3Ptr;
}

#endif // DOXYGEN_SHOULD_SKIP_THIS

   ----------

//
// FelkelIntersection.h: interface for the CIntersection class.
//
// Copyright (c) 2003-2006 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//
// Straight skeleton algorithm and original implementation
// courtesy of Petr Felkel and Stepan Obdrzalek (petr.felkel@...)
// Re-implemented for the Virtual Terrain Project (vterrain.org)
// by Roger James (www.beardandsandals.co.uk)
//

#ifndef FELKELINTERSECTIONH
#define FELKELINTERSECTIONH

#ifndef DOXYGEN_SHOULD_SKIP_THIS

#include <queue>

#include "FelkelComponents.h"
class CSkeleton;

typedef priority_queue <CIntersection, deque <CIntersection>, greater
<CIntersection> > IntersectionQueue;

class CIntersection
{
public:
	 CIntersection (void) { };
	 CIntersection (CVertexList &vl, CVertex &v);

	 void ApplyNonconvexIntersection(CSkeleton &skeleton, CVertexList &vl,
IntersectionQueue &iq, bool bCheckVertexinCurrentContour);
	 void ApplyConvexIntersection(CSkeleton &skeleton, CVertexList &vl,
IntersectionQueue &iq);
	 void ApplyLast3(CSkeleton &skeleton, CVertexList &vl);

	 C3DPoint m_poi;
	 CVertex *m_leftVertex, *m_rightVertex;
	 CNumber m_height;
	 enum Type { CONVEX, NONCONVEX } m_type;

	 bool operator > (const CIntersection &i) const
	 {
		 // Do exact comparison for intersection queue
		 // Using CNumber will also test for != which is implemented as !SIMILAR
		 double d1 = m_height;
		 double d2 = i.m_height;
		 return d1 > d2;
	 }
	 bool operator == (const CIntersection &i) const
	 {
		 return m_poi == i.m_poi;
	 }
};

#endif // DOXYGEN_SHOULD_SKIP_THIS
#endif // FELKELINTERSECTIONH


[Non-text portions of this message have been removed]

#5301 From: "Bryan Berg" <bberg@...>
Date: Mon Apr 7, 2008 7:48 pm
Subject: adding 2d image to terrain
bberg@...
Send Email Send Email
 
Hi,



I need to add a 2D image to the 3D terrain (migrating from 2D terrain to 3D
terrain - eventually we will have a 3D object).



I've been looking at enviro and reading on enviro tutorials but cannot seem
to get the layers menu to load. (using mfcenviro).



Any hints to objects/methods required to add a small 2D image (bmp) to my
terrain ?



Thanks !



-Bryan







[Non-text portions of this message have been removed]

#5302 From: "Bryan Berg" <bberg@...>
Date: Mon Apr 7, 2008 8:14 pm
Subject: adding 2d image to terrain ... continued
bberg@...
Send Email Send Email
 
Oh and I forgot to mention that I need to this from code, ie not load an
object from a configuration file.



This is because the location of the object will change from time to time and
this needs to be set dynamically.



-Bryan



[Non-text portions of this message have been removed]

Messages 5273 - 5302 of 6247   Oldest  |  < Older  |  Newer >  |  Newest
Add to My Yahoo!      XML What's This?

Copyright 2010 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines NEW - Help