Algoritmo de generación automática de techo 3D de polígono arbitrario

Algoritmo de generación automática de techo 3D variable arbitraria


        He estado en CSDN cat durante un año y puedo encontrar muchos recursos aquí, especialmente Android. Pero nunca escribí un blog. Estoy agradecido de encontrar respuestas a mis preguntas en algunos blogs excelentes. Por lo tanto, a partir de hoy seguiré el ejemplo de todos y escribiré algunas de las cosas que he hecho. Se siente más valioso para las discusiones técnicas. Si no está claro, las críticas y las discusiones son bienvenidas.

       El primero es escribir sobre un algoritmo de techo tridimensional realizado en octubre de este año. Este algoritmo es la base para el proyecto de investigación previa de 3D GIS que construye automáticamente edificios basados ​​en datos de mapas. Encontré muchos problemas en ese momento y recientemente tuve que escribir algunos documentos de algoritmos y publicarlos por cierto para discutir y aprender unos de otros. Este algoritmo implica la compilación y el uso de la biblioteca de geometría CGAL. ​​Espero dar una pista a los amigos que compilan esta biblioteca por primera vez. Además, aunque este algoritmo se basa en CGAL, todavía no estoy familiarizado con el uso de la biblioteca CGAL. CGAL es una biblioteca muy poderosa, un recurso indispensable de alta calidad para figuras geométricas. A continuación se describe el proceso de implementación del algoritmo para la generación automática de cubiertas poligonales 3D arbitrarias.


1. Requisitos de la tarea:

1. El techo inclinado se genera automáticamente de acuerdo con los vértices de la secuencia de polígono proporcionada y el tipo de parámetro de entrada.

2. Se permiten agujeros en la deformación múltiple de entrada y el número de agujeros es arbitrario.

3. Exporte el techo poligonal generado en formato de modelo OSG.

4. El algoritmo requiere estabilidad, alta eficiencia y puede aceptar cualquier prueba.

2. Diseño de algoritmos

1. Ideas de diseño

De acuerdo con las necesidades de la tarea, el algoritmo de esqueleto poligonal arbitrario Straight_skeleton_2 en la biblioteca de código abierto CGAL se selecciona como la función de generación del esqueleto subyacente. Al generar la ruta más corta del borde del esqueleto obtenido, se debe alcanzar la relación topológica de deformación múltiple de la superficie del techo. Al establecer el ángulo de la pendiente del techo, se obtiene el valor de altura del punto del esqueleto. Renderice las coordenadas de punto del esqueleto generadas y la relación topológica con la escena OSG para generar un modelo de formato OSG.

2. Pasos del proceso

   (1) Compile la biblioteca de código abierto CGAL.

   (2) Obtenga la relación topológica del polígono a la línea del esqueleto del algoritmo Straight_skeleton_2.

   (3) El algoritmo de ruta más corta se usa para atravesar y verificar los bordes del esqueleto para generar polígonos de techo.

   (4) Establezca la altura del punto del esqueleto de acuerdo con la distancia entre el punto del esqueleto y la línea del esqueleto adyacente.

   (5) Corte el techo de acuerdo con la altura del techo establecida para generar el plano de techo correspondiente.

   (6) Ingrese la relación de topología del techo generada en la escena OSG y renderice el formato del modelo OSG.

En tercer lugar, el proceso de implementación del algoritmo

1. Compilación de bibliotecas de código abierto CGAL

  CGAL es una biblioteca de algoritmos geométricos de código abierto relativamente clásica, el algoritmo es clásico, estable y eficiente. Es difícil de compilar y debe configurarse de acuerdo con los pasos correspondientes para tener éxito. Hay tres dificultades principales: Necesito confiar en la biblioteca BOOST, el entorno QT, LibQGLviewer. 2. Es difícil configurar el entorno correspondiente y el problema de configuración provoca directamente que falle la compilación. 3Debido al problema de versión causado por el proceso de compilación de la biblioteca BOOST, es necesario modificar el nombre del archivo de la biblioteca correspondiente; de ​​lo contrario, la compilación falla. (En resumen, es problemático, ¡pero siempre se puede compilar! Serio + cuidado + perseverancia = CGAL compilado con éxito, ¡vamos!) Hay muchos ejemplos en Internet, pero siempre aparecen situaciones diferentes en diferentes entornos. Aquí está mi propia compilación proceso…….

(1) Preparación

Sistema operativo nativo: Win7 + VS2010

【Boost_1_56_0】

【CGAL-4.2】

【Cmake-2.8.0-win32-x86】

【Qt-opensource-windows-x86-vs2010-4.8.6】

【LibQGLViewer】

       Si quieres hacer cosas buenas, primero debes perfeccionar tus herramientas. Aunque algunos internautas dicen que necesitas algunas funciones sin instalar ciertos módulos, pero para aquellos que no tienen experiencia en la compilación de bibliotecas de código abierto, deben ser honestos y estar completamente preparados para lo anterior. Las cosas anteriores son las mejores. No te pierdas lo mismo. De lo contrario, sabrá ... Utilizo esta versión y la prueba es exitosa, pero no es la única solución. Puede consultar a otros internautas. Busque en Duma el enlace de descarga de la versión.

Nota: Algunos internautas dijeron que la biblioteca BOOST es mejor para usar la versión de instalación en línea, pero parece que la página web no es válida, solo use boost_1_56_0. También existe CGAL. ​​Necesita estar conectado a Internet durante la instalación. A veces la velocidad de la red es lenta y algunos archivos no se descargan. Mi solución es copiar la dirección al navegador para descargarla y luego ponerla en la carpeta correspondiente, que se mencionará específicamente a continuación.

(2) El primer lote de instalación y configuración

Dificultad y fácil, comienza con caquis suaves. Instale QT, libQGLViewe, Cmake a su vez, descomprima BOOST en una carpeta, aquí mi carpeta es D: \ Instruct.

Para evitar el error de configuración de la variable de ruta, a continuación se muestra la configuración de la variable de entorno de instalación de ruta, ¡esto es muy importante! Si no sabe cómo configurar las variables de entorno, vaya a la esquina y piénselo un rato.

RUTA: D: \ CGAL-4.2; D: \ CGAL-4.2 \ auxiliary \ gmp \ lib;

D: \ Instruir \ cmake \ cmake-2.8.10-win32-x86 \ bin;

C: \ Qt \ 4.8.6 \ bin; C: \ Qt \ bin;

D: \ Instruir \ boost_1_56_0 \ boost_1_56_0;

      C: \ CGAL \ lib;

 

BOOST_INCLUD: D: \ Instruir \ boost_1_56_0 \ boost_1_56_0

BOOST_LIBRAR : D: \ Instruir \ boost_1_56_0 \ boost_1_56_0 \ stage \ lib

BOOST_ROOT: D: \ Instruir \ boost_1_56_0 \ boost_1_56_0

(3) Autocompilación de la biblioteca BOOST

Esta ruta D: \ Instruct \ boost_1_56_0 \ boost_1_56_0 \ stage \ lib no existe antes de la compilación. Primero debe ejecutar bootstrap.bat para generar y luego ejecutar el bjam.exe generado; no hablaré de ello en detalle, consulte los procedimientos de otros usuarios. Esta parte debe esperar 20 minutos.

(4) Instale CGAL y establezca la ruta de la variable de entorno.

   Se requiere conexión a Internet durante la instalación. Si la velocidad de Internet es lenta y la descarga del archivo falla, use el navegador para descargarlo como se le solicita. Luego colóquelo en el directorio de carpetas correspondiente.

(5) Iniciar Cmake

                                    aax01

Figura 1 Configuración de ruta de Cmake

Establezca la ruta correspondiente de acuerdo con la Figura 1 anterior. Luego haga clic en configurar y se le pedirá que seleccione el compilador. Usé VS2010. El proceso de selección de 2010 es de aproximadamente dos minutos. Si no hay nada malo, haga clic en generar, y habrá un CGAL.sln debajo de la ruta de salida que seleccionó. El problema se acerca. En muchos casos, se mostrarán varias excepciones. El motivo es que la ruta está configurada incorrectamente. La compilación correcta mostrará las siguientes tres líneas. Si la ruta es correcta y hay errores, modifique el nombre del archivo de acuerdo con el mensaje de error del problema y verifique lo siguiente Si la configuración en los tres datos es correcta.

D: /CGAL-4.2/auxiliary/gmp/lib/libgmp-10.lib

MPFR incluye: D: /CGAL-4.2/auxiliary/gmp/include

Bibliotecas MPFR: D: /CGAL-4.2/auxiliary/gmp/lib/libmpfr-4.lib

(6) Abra CGAL.sln y ejecútelo de nuevo en los modos Debug y Release. Muestra éxito 5 y error 0. CGAL-vc100-mt.lib, CGAL-vc100-mt-gd.lib y otras bibliotecas se generarán en la carpeta lib bajo la ruta de salida.

Esto se considera compilado.

Si compila correctamente una vez, tiene demasiada suerte para TMD. Si se compila en un día, significa que eres inteligente, si son dos días, significa que eres capaz, y si se compila en tres días, ¡significa que tienes perseverancia! ¡Tengo mucha perseverancia, ja, ja! ¡Las lágrimas casi salían cuando la configuración tuvo éxito!

2. Obtenga la relación topológica del borde del esqueleto a través del algoritmo de generación de esqueleto Straight_skeleton_2

referencia:

http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Straight_skeleton_2/Chapter_main.html

Como se muestra en la Figura 2,

Los círculos negros representan los vértices de entrada, los círculos azules representan los puntos del esqueleto generados y las líneas rojas son los bordes del esqueleto.

 ss01

Figura 2

La función de salida del esqueleto (código de la siguiente manera) dada por el ejemplo Straight_skeleton_2 puede generar los puntos y los bordes del esqueleto generados.

plantilla < clase K>

void print_straight_skeleton (CGAL :: Straight_skeleton_2 <K> const & ss) (1)

{

  typedef CGAL :: Straight_skeleton_2 <K> Ss;

 

  typedef typename Ss :: Vertex_const_handle Vertex_const_handle;

  typedef typename Ss :: Halfedge_const_handle Halfedge_const_handle;

  typedef typename Ss :: Halfedge_const_iteratorHalfedge_const_iterator;

 

  Halfedge_const_handle null_halfedge; // Manija de control de medio borde

  Vertex_const_handle null_vertex; // identificador de control de vértice

 

  std :: cout << " Esqueleto recto con" << ss.size_of_vertices () // 顶 点数

            << "vértices", << ss.size_of_halfedges () // Número de medias aristas

            << "medios bordes y" << ss.size_of_faces () // 骨架 面 数

            << "caras" << std :: endl;

           

  para (Halfedge_const_iterator i = ss.halfedges_begin (); i! = ss.halfedges_end (); ++ i)

  {

    print_point (i-> opuesto () -> vértice () -> punto ()); // Muestra las coordenadas del punto inicial del borde del esqueleto

    std :: cout << "->" ;

    print_point (i-> vertex () -> point ()); // Muestra las coordenadas del punto final del borde del esqueleto

std :: cout << "" << (i-> is_bisector ()? "bisector" : "contorno" ) << std :: endl;

// "bisectriz": "contorno" borde original: borde de contorno generado

  }

}

En el ejemplo, solo se da la salida de información del lado del esqueleto y no hay salida de la superficie del esqueleto Estoy tratando de encontrar la función de control de la superficie del esqueleto.

typedef typename Ss :: Face_const_handle Face_const_handle;

typedef typename Ss :: Face_const_iterator Face_const_iterator;

Pero no hay una indicación inteligente del método de salida de la superficie del esqueleto. Después de buscar durante mucho tiempo, encontré algunas funciones sobre cara, pero no tuve éxito en la operación, y luego abandoné la idea de obtener directamente la relación topológica de la superficie del esqueleto, porque se puede usar el algoritmo de ruta más corta para encontrar cada borde original de acuerdo con la relación entre el borde original y el borde del esqueleto. La superficie del esqueleto correspondiente.

3. El algoritmo de ruta más corta obtiene el polígono del techo.

Como se muestra en la Figura 3, los vértices 1-8 son los vértices del polígono original y el 9-13 son los puntos del esqueleto generados La relación de conexión se muestra en la figura y se puede obtener mediante la función (1) en Straight_skeleton_2. Usando el algoritmo de ruta más corta, establezca el peso del lado del enlace original en infinito (lado negro: 1000000) y establezca el peso del lado del esqueleto generado en 1 (lado rojo), y luego calcule el lado original 1-> 2,2-> 3 a su vez , ..., el camino más corto de 8-> 1. Se puede obtener la superficie del esqueleto correspondiente a cada borde original.

La referencia de algoritmo de ruta más corta: DijkstraShortestPathAlg.

 sss01

imagen 3

4. Cálculo del valor de elevación del punto del esqueleto

Las coordenadas del punto del esqueleto calculadas por Straight_skeleton_2 son coordenadas planas. Para obtener un techo tridimensional, simplemente asigne un valor de altura al punto del esqueleto generado. Pero este valor de altura es una configuración subjetiva, tal vez desee que la altura de cada punto sea diferente, lo que puede ser más realista. Por lo tanto, aquí hay un método para calcular automáticamente la altura del punto del techo estableciendo el ángulo de inclinación del techo. Como se muestra en la Figura 3, en un pentágono (1-11-12-13-2) en una superficie de esqueleto, se puede obtener multiplicando la distancia desde el vértice 11, 12, 13 hasta el borde (1-2) por la tangente del ángulo del techo. Su valor de altura. Por supuesto, esto es solo una regulación, asumiendo que los valores de altura de los puntos originales son iguales. También puede establecer otras reglas.

5 Establezca la altura del plano del techo para obtener la sección del techo

ss01

Figura 4 (a)

Como se muestra en la Figura 4 (a), es el techo inclinado total generado, pero a veces nuestros techos no son todos inclinados, sino aleros inclinados, con techos planos, como un bisel. Entonces, de acuerdo con el algoritmo anterior, obtenemos la altura del punto del techo (es decir, el punto del esqueleto) y luego usamos un plano de cierta altura para ser tangente al techo para obtener una sección tangente. Por supuesto, a veces hay varias secciones de corte, lo que requiere que configuremos un método determinado para encontrarlas.Como se muestra en la Figura 4 (b), la parte roja es la sección de corte.

sss01

Figura 4 (b)

6 Renderizar en formato de modelo OSG

La relación topológica de la superficie del techo se puede obtener a través de los primeros pasos, y luego el proceso de lectura en el proceso de renderizado OSG. Por supuesto, OPENGL es adecuado. Siempre que la topología del modelo sea renderizada por qué motor, depende de sus propias preferencias. Si desea que el modelo de techo final esté en formato OSG, por supuesto, debe compilar la biblioteca OSG. Para este proceso, consulte los blogs de otros internautas.

Guarde como un modelo OSG con esta función: osgDB :: writeNodeFile (* (root.get ()), "RzXpdRoof.osg" ); Una línea de código, puede guardar la escena de dibujo como un modelo OSG.

Cuarto, la implementación del código principal del algoritmo.

(1) Algoritmo de generación de esqueleto Straight_skeleton_2 para obtener la relación topológica de los bordes del esqueleto

Consulte el código de muestra en el ejemplo en CGAL: http://doc.cgal.org/latest/Straight_skeleton_2/index.html

En la función (1), puede agregar el siguiente código para ver el número de vértice:

std :: cout <<i-> opuesto () -> vértice () -> id () << "" << i-> vértice () -> id ();

(2) Generación de techo y búsqueda de sección de corte

Para obtener más información, consulte la función en el código fuente print.h: ROOFgetxpd_straight_skeleton (CGAL :: Straight_skeleton_2 <K> const & ss, PLOYGON merofploy, float Angle, float maxhight)

 

(3) Para el renderizado OSG, consulte el archivo main.cpp en el proyecto C: \ Users \ zyp \ Desktop \ 1111111111

(4) Finalmente, el proyecto de integración es la sección MFC para probar, consulte el proyecto C: \ Users \ zyp \ Desktop \ SSZRidegLine para obtener más detalles

Cinco, análisis de prueba de algoritmo

Me tomó casi tres semanas implementar todo este conjunto de procedimientos, ahora el pensamiento es claro y me siento muy simple, pero fue muy difícil cruzar el río sintiendo las piedras. Dificultades: 1. Compilación CGAL; 2. Descubrir la relación topológica de los bordes del esqueleto; 3. Encontrar la cara del esqueleto (Usé el algoritmo de ruta más corta para obtenerla. Aún no sé cómo operar la cara del esqueleto, por favor ilumíneme si está familiarizado con CGAL); 4. Encuentra la sección de corte.

Especialmente cuando encontré la sección transversal, el algoritmo que comencé era complicado y había errores. La depuración en este lugar estuvo atascada durante casi una semana o dos. Fue realmente doloroso. El 80% de las veces obtuve el resultado correcto, el otro era el triángulo equivocado. Al principio sospeché que mi modo de renderizado era incorrecto, después de muchas pruebas, me di cuenta de que el algoritmo para encontrar la sección de corte no era riguroso. Después de darse cuenta de dónde estaba el problema, se resolvió en un día.

 ss01

Figura 5 Polígono arbitrario sin huecos

sss01

Figura 6 Situación con agujeros

La estructura ROOF se define en el proyecto SSZRidegLine para almacenar la topología del modelo generado.

El formato de lectura de la entrada del polígono se define en el proyecto C: \ Users \ zyp \ Desktop \ SSZRidegLine \ cinploys.txt (el polígono más externo del polígono se ordena en el sentido de las agujas del reloj y el agujero en el sentido contrario)

PloygonNum: 6 10 3 12 5 7 3

6: Significa que hay seis polígonos en total //

Ploygonouter: representa el polígono más externo //

ploygonhole: // indica un agujero en el polígono

10 3 12 5 7 3 indican respectivamente el número de vértices de 6 polígonos.

ploygonouter:

134.000 97.0000.000 /// Coordenadas (x, y)

273.000 68.0000.000

561.000 62.0000.000

530.000 298.0000.000

455.000 381.0000.000

363.000 130.0000.000

279.000 260.0000.000

148.000 206.0000.000

127.000 320.0000.000

91.000 117.0000.000

ploygonhole:

227.000 116.0000.000

197.000 149.0000.000

264.000 187.0000.000

ploygonhole:

481.000 119.0000.000

445.000 151.0000.000

453.000 193.0000.000

487.000 192.0000.000

510.000 183.0000.000

515.000 151.0000.000

517.000 114.0000.000

505.000 91.0000.000

449.000 81.0000.000

391.000 104.0000.000

406.000 124.0000.000

440.000 118.0000.000

ploygonhole:

464.000 253.0000.000

455.000 273.0000.000

469.000 293.0000.000

486.000 289.0000.000

501.000 264.0000.000

ploygonhole:

153.000 185.0000.000

204.000 209.0000.000

220.000 195.0000.000

137.000 148.0000.000

150.000 126.0000.000

118.000 121.0000.000

115.000 153.0000.000

ploygonhole:

336.000 99.0000.000

295.000 117.0000.000

317.000 133.0000.000

 

Formato de archivo de modelo de salida

C: \ Users \ zyp \ Desktop \ SSZRidegLine \ Debug \ faceoutxpd.txt

RoofObject: 1 3 11 14

///

1: Significa que el techo está aplanado, y el número de veces de esta posición es 0, lo que significa que el techo está estrictamente inclinado

3: Indica que el techo lo generan tres polígonos (es decir, hay dos huecos)

11: indica que el polígono más externo tiene 11 vértices

14: indica que hay 14 caras de techo

///

PosId: 35 4 3 4

0 907.000 140.000 0.000 // número de serie 0; coordenadas (x, y, z)

1916.000 459.000 0.000

2 116.000 420.000 0.000

3228.000 100.000 0.000

4 382.000 197.000 0.000

5332.000 259.000 0.000

6 507.000 332.000 0.000

7814.000 257.000 0.000

8 709.000 287.000 0.000

9 705.000 390.000 0.000

10811.000 390.000 0.000

11 675,253 418,615 28,592

12 624,759 414,220 30,522

13842.971 422.701 32.675

14380.184 143.822 34.769

15861.972 194.873 46.521

16 862.564 404.457 51.835

17 855.390 190.053 52.959

18 230.129 284.846 63.023

19640.432 380.605 64.833

20 285,195 185,860 82,282

21 618,737 216,125 92,871

22 250.119 329.674 96.673

23 589.450 242.684 121.084

24 882,637 163,628 25,000

25 890.228 432.694 25.000

26 150.684 396.641 25.000

27 245.378 126.087 25.000

28 380.694 158.763 25.000

29 291.590 269.253 25.000

30 603.455 399.345 25.000

31 839.780 223.614 25.000

32 684.702 267.921 25.000

33 678.990 415.020 25.000

34 835.462 415.020 25.000

Cara: 4 // La cara del techo tiene 4 vértices

3 27 24 0 La relación de conexión de la superficie del techo; registre el número de vértice

Rostro: 4

0 24 25 1

Rostro: 4

1 25 26 2

Rostro: 4

2 26 27 3

Rostro: 4

6 30 28 4

Rostro: 4

4 28 29 5

Rostro: 4

5 29 30 6

Rostro: 4

10 34 31 7

Rostro: 4

7 31 32 8

Rostro: 4

8 32 33 9

Rostro: 4

9 33 34 10

Rostro: 4

27 24 25 26 27

Rostro: 3

30 28 29 30

Rostro: 4

34 31 32 33 34

¡La introducción del algoritmo ha terminado!

Si está interesado, deje un comentario y proporcione el código.

 

Supongo que te gusta

Origin blog.csdn.net/sun19890716/article/details/42679161
Recomendado
Clasificación