( Read & Write ) Entender un poco mejor el lenguaje

Feb 23, 2013 at 3:30 PM
Daniel como bien me dijiste en el email me dispongo a preguntar por aquí para entender un poco mejor C# y las librerías.

Resulta que estoy realizando una aplicación que la primera consiste exactamente un poco en lo que se basan estas librerías.

Debo cargar el archivo .dxf ( la planta del planol) y poder añadir una nueva capa o varias capas a este .dxf ( cosas sencillitas) y poder guardar el archivo y obtener en la salida un nuevo .dxf

Mi pregunta es la siguiente, para ver si voy entendiendo un poco vuestras librerías, me gustaría que la visualización del .dxf fuera en un PictureBox, no se si es posible.

En todo caso estoy poniendo:

//Cargar la Imagen
              DxfDocument dxf = new DxfDocument();
              dxf.Load(ofdAbrirPlano.FileName);
me sale un error en la clase TextStyle.

Muchas gracias.
Coordinator
Feb 24, 2013 at 3:04 PM
No es ningún problema añadir nuevas capas a un documento previamente cargado. Puedes añadirlas mediante el método public Layer AddLayer(Layer layer) del documento dxf. También para cualquier nueva entidad que se añade al documento se comprueba previamente si la capa asignada a este existe o no, en caso negativo se agregará automáticamente. Una vez realizados los cambios puedes volver a guardar el dxf.

En cuanto a la visualización en un PictureBox eso tendrás que programarlo por tu cuenta, si lo único que necesitas es dibujar líneas es sencillo hacerlo con los elementos que ya incluye el GDI. Para el caso de circunferencias y arcos incluí en estas clases un método para descomponer la curva en un polígono dada una precisión.

Por último, si te da un error la carga de un archivo, primero asegurate de que la versión del dxf es AutoCad2000 o posterior, si es así necesitaría mas detalles del error generado o facilitarme el dxf para poder echarle un vistazo, para poder saber a que es debido.

Daniel
Mar 1, 2013 at 11:49 PM
Buenas de nuevo Daniel,

primero disculparme si parezco excesivamente ignorante con el código pero no tengo demasiada experiencia en este lenguaje.

Finalmente he comprendido que las librerías que usted facilita son para poder leer y escribir en un archivo .dxf, en ningún caso crear un display, si deseará hacer un display ya me tendría que aventurar con GDI+ ( creo, no lo se exactamente).

Ahí tengo mis preguntas,

Por lo que he podido ver,
  DxfDocument dxf = new DxfDocument();

  // save to file
  dxf.Save(filename, DxfVersion.AutoCad2000);
  // load file
  dxf.Load(filename);
Si realizas esta acción te crea un archivo dxf en blanco. Sin embargo si le añades:
  DxfDocument dxf = new DxfDocument();
  // add your entities here
  dxfDocument.AddEntity(entity);
  // save to file
  dxf.Save(filename, DxfVersion.AutoCad2000);
  // load file
  dxf.Load(filename);
Te crea un .dxf con las entidades añadidas, en el caso de ser una recta, pues te crea una recta, si es un punto pues un punto.

Mi pregunta es, si lo que quiero es poder leer un archivo ya existente, y una vez leído por ejemplo añadir una capa y en esta añadir un polígono que funciones debería utilizar.

Se lo comento porque no se si al usar Dxfread, debo leer todas las entidades o hay una manera directa de leer todo, y en el dxfwrite no lo acabo de entender, porque utilizando addentity ya estas escribiendo en el .dxf.

Muchas gracias y por cierto gracias por el gran trabajo que has realizado en este proyecto.
Coordinator
Mar 3, 2013 at 2:01 AM
Lo primero actualiza el código de la librería y vuelvelo a compilar, hay un par de cambios importantes en como se guardan y se cargan los archivos.
// la función Load es ahora estática
// sample.dxf todos los tipos de entitdades soportadas por netDxf
DxfDocument dxf = DxfDocument.Load("sample.dxf");

// la versión del dxf se controla mediante la propiedad DrawingVariables del documento dxf
// también puede pasarse una instancia de HeaderVariables
// o un DxfVersion al constructor para inicializar una nueva instancia de DxfDocument
dxf.DrawingVariables.AcadVer = DxfVersion.AutoCad2010;
dxf.Save("sample copy.dxf");
Sobre tus dudas, toda la interacción con un dxf debe hacerse a través del DxfDocument, no se a que te refieres con el "Dxfread" o el "dxfwrite", si es a las clases DxfReader y DxfWriter estas son clases internas y no deben utilizarse independientemente. Cuando cargas un archivo mediante DxfDocument.Load este cargará toda la información del dxf, al menos todo aquello que es capaz de entender, y lo tendrás disponible a través de sus propiedades. En el directorio doc encontrarás el archivo "netDxf Documentation.chm" allí encontrarás la documentación de las clases, sus métodos y propiedades.

Ahora un poco de código sobre el tema de las capas.
// cargamos un archivo externo si así se requiere
// si simplemente hacemos DxfDocument dxf = new DxfDocument() lo único que haremos será crear un documento vacío
DxfDocument dxf = DxfDocument.Load("sample.dxf");
// así obtendrás la lista completa de capas en el documento
ReadOnlyCollection<Layer> layers = dxf.Layers;
// pudiendo acceder a la información de cada una de ellas
string name = layers[1].Name;
// si conoces el nombre de las capas también puede acceder a ellas así
Layer layer = dxf.GetLayer(name);

// si queremos añadir una nueva
Layer newLayer = new Layer("MiNuevaCapa");
// y le podemos cambiar el color
newLayer.Color = AciColor.Green;
// ahora podemos añadirla al documento
dxf.AddLayer(newLayer);

// las capas de las entidades que se añadan al documento también se incluirán, si no existen previamenate
Layer otherLayer = new Layer("OtraCapa");
Line line = new Line(new Vector3(0, 10, 0), new Vector3(0, 50, 0));
line.Layer = otherLayer;
// añadimos la entidad line al documento, la capa otherLayer también formará parte del documento
dxf.AddEntity(line);

// guardamos los cambios en otro archivo
dxf.Save("sample copy.dxf");
Para dibujar un polígono tendrás primero que calcular sus vértices para luego dibujarlos mediante entidades Line, o al ser en este caso un elemento bidimensional una LwPolyline cerrada es suficiente, aunque optar por una Polyline tampoco te dará problemas.
// un cuadrado mediante una polilínea cerrada
List<LwPolylineVertex> vertexes = new List<LwPolylineVertex>
                                                  {
                                                      new LwPolylineVertex(-0.5, -0.5),
                                                      new LwPolylineVertex(0.5, -0.5),
                                                      new LwPolylineVertex(0.5, 0.5),
                                                      new LwPolylineVertex(-0.5, 0.5)
                                                  };
LwPolyline square = new LwPolyline(vertexes, true);
dxf.AddEntity(square);
De momento no tengo previsto realizar ningún tipo de control donde volcar gráficamente la información contenida en un dxf, ya se mediante GDI, OpenGL o DirectX; esto por ahora corre de vuestra cuenta. Y por favor tuteame, me resulta extraño.

Daniel
Mar 8, 2013 at 4:24 PM
Edited Mar 8, 2013 at 4:33 PM
Gracias de nuevo Daniel.

Ahora mismo estoy probando sus librerías, y estaba intentando hacer lo siguiente pero no consigo resultados.

Con el ejemplo que expuso anteriormente por ejemplo, yo creo un polígono a través de lwpolyne

List<LwPolylineVertex> vertexes = new List<LwPolylineVertex>
                                              {
                                                  new LwPolylineVertex(-0.5, -0.5),
                                                  new LwPolylineVertex(0.5, -0.5),
                                                  new LwPolylineVertex(0.5, 0.5),
                                                  new LwPolylineVertex(-0.5, 0.5)
                                              };
        LwPolyline square = new LwPolyline(vertexes, true);
Imagínese que simplemente voy a crear un programa con dos botones, el primero me crea un .dxf y a la vez me crea el polígono con el código anterior, y el segundo botón cuando le doy me devuelve los valores de los vértices, es decir,

(-0.5, -0.5),
(0.5, -0.5),
(0.5, 0.5),
(-0.5, 0.5)

Si en el primer botón yo añado este código,

LwPolylineVertex vertice1 = vertexes[0];

MessageBox.Show("El vertice 1 es " + vertice1.ToString());

me devuelve "LwPolylineVertex(-0.5, -0.5)" ---->>>> me gustaría que solo me devolviera -0.5,0.5

pero claro, la gracia es que usando un segundo botón pueda cargar el dxf, y acceder a los vértices, que me los devuelva numéricamente, para poder usar esa información de manera matemática.

Si quisiera acceder al polígono a través de su capa asociada, ya he visto que no es posible , ya que layer tiene las propiedades de codename,color,default, handle, is visible, linetype,linewight y plot.

Por cierto yo lo he intentado con:

private void button9_Click(object sender, EventArgs e)
    {
        // Acceder a las coordenadas declaradas en el dxf
       DxfDocument dxf = DxfDocument.Load("sample.dxf");
       List<LwPolylineVertex> vertices = dxf.LwPolylines.Vertexes;

    }
Pero me señala en rojo Vertexes

Si me pudiera guiar un poco se lo agradecería.

Saludos y gracias de nuevo.
Coordinator
Mar 12, 2013 at 12:03 AM
Edited Mar 12, 2013 at 4:30 AM
Parece que la gente de Codeplex ya han solucionado sus problemas con los mensajes de los foros.

No tienes porque utilizar la función ToString() si no quieres o no te devueleve el texto que tu quieres, contruye tu propia cadena de texto para representar la variable a partir de los datos que almacena el vértice de la polilínea. LwPolylineVertex contiene la propiedad Location que te devolverá un Vector2 donde se almacenan las coordenadas del vértice.

Lo primero que deberías hacer es adquirir unos conocimientos básicos de programación y familiarizarte con el funcionamiento y los tipos básicos del net framework. Tus problemas tiene la raiz en una falta de conocimientos básicos en programación y estos los deberías adquirir previamente, por ejemplo en la línea:
List<LwPolylineVertex> vertices = dxf.LwPolylines.Vertexes;
Lógico que te de un error. dxf.LwPolylines contiene una lista con TODAS las LwPolylines del documento y Vertexes contiene los vértices de UNA LwPolyline, primero deberías especificar cual de todas las LwPolylines del documento es de la que quieres obtener sus vértices. Este tipo de dudas se salen del uso lógico de la librería, un libro te será más útil para aprender a programar que los mensajes en un foro.

Por último, de momento, no hay una función que te devuelva las entidades contenidas en una capa, pero siempre puedes iterar sobre los elementos de la lista hasta obtener las entidades que esten en la capa que buscas.

Daniel