Russian Qt Forum

Qt => Общие вопросы => Тема начата: 8Observer8 от Март 29, 2014, 07:36



Название: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 07:36
Привет! Есть такой пример с трёхмерной фигурой, в котором массив вершин (координаты), массив индексов и массив цветов вершин генерируются в самой программе:

Массив координат:
Код
C++ (Qt)
void Scene3D::getVertexArray() // определить массив вершин
{
   GLfloat R=0.75; // радиус сферы
 
   // начальные значения для икосаэдра
   GLfloat a=4*R/sqrt(10+2*sqrt(5)); // сторона икосаэдра
   GLfloat alpha=acos((1-a*a/2/R/R)); // первый угол поворота по тэта
   // cos(alpha)=(1-a*a/2/R/R)
 
   // вычисляем точки икосаэдра
   //0 точка
   VertexArray[0][0]=0;   // x
   VertexArray[0][1]=0;   // y
   VertexArray[0][2]=R;   // z
 
   //1 точка
   VertexArray[1][0]=R*sin(alpha)*sin(0);
   VertexArray[1][1]=R*sin(alpha)*cos(0);
   VertexArray[1][2]=R*cos(alpha);
 
   // ...
}
 

Массив индексов:
Код
C++ (Qt)
void Scene3D::getIndexArray()   // определить массив индексов
{
   // 0 треугольник
   IndexArray[0][0]=0; // индекс (номер) 1-ой вершины
   IndexArray[0][1]=2; // индекс (номер) 2-ой вершины
   IndexArray[0][2]=1; // индекс (номер) 3-ей вершины
 
   // 1 треугольник
   IndexArray[1][0]=0;
   IndexArray[1][1]=3;
   IndexArray[1][2]=2;
 
   // ...
}
 

Массив цветов вершин:
Код
C++ (Qt)
void Scene3D::getColorArray() // определить массив цветов вершин
{
   for (int i=0; i<12; i++)
   {
       ColorArray[i][0]=0.1f*(qrand()%11); // R - красная составляющая
       ColorArray[i][1]=0.1f*(qrand()%11); // G - зелёная составляющая
       ColorArray[i][2]=0.1f*(qrand()%11); // B - синяя составляющая
       // qrand()%11 - псевдослучайное число от 0 до 10
   }
}
 

Описание примера: http://www.gamedev.ru/code/articles/OpenGL_Qt4
Исходники на Qt5: https://github.com/8Observer8/Icosahedron

Подскажите, пожалуйста, есть ли простой бесплатный редактор, в котором можно нарисовать 3D-фигуру, и чтобы этот редактор сгенерировал файл с массивом вершин, массивом индексов и массивом цветов вершин?

Заранее спасибо за ответ!


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Март 29, 2014, 07:39
Blender.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 07:45
Blender.

О, отлично! Бесплатный редактор :) Огромное спасибо! Если не будет получаться, то я здесь напишу :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 08:36
Когда запускаешь Blender, то появляется куб. Как сохранить этот куб, чтобы я мог открыть файл из Qt и считать координаты, массив индексов и т.д.? Я пытался "Сохранить как...", но он сохраняет в своём формате ".blend"


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Март 29, 2014, 08:41
А вам самому интересно так изучать?

Почитайте про простые текстовые форматы хранения, например, obj.
Экспортируйте модель в него и читайте потом из своей программы.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 10:18
Спасибо! Значит можно, как-то экспортировать. Вот только вопрос как? Если в гугле найду, то отпишусь здесь. "obj" - у меня ассоциируется с объектным файлом :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Март 29, 2014, 10:32
3D-фигуру, и чтобы этот редактор сгенерировал файл с массивом вершин, массивом индексов и массивом цветов вершин?
Vertex (vertices), можно по-русски "вертекс(ов)". И Вы забыли самый главный массив создать который обычно 80% работы и более


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 10:41
И Вы забыли самый главный массив создать который обычно 80% работы и более
Какой же? В примере больше нет массивов. Массив координаты вершин. Потом вершины нумеруют и для каждого примитива формируют массив индексов. Ещё массив цветов вершин. Вроде ничего не забыл :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Март 29, 2014, 11:00
И еще одного массива нет. Его создание бывает или очень простым или непосильно сложным.
А еще раз скажете "вершина" - перестану отвечать


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 11:07
Я не понимаю, о чём идёт речь? :) Как я понял, Vertex у меня есть. Его можно сгенерировать программно, как в данном примере. А можно нарисовать фигуру в редакторе и загрузить Vertex из файла. Вы говорите о Vertex?


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 11:26
Вот здесь написано, что Blender может в XML экспортировать: http://online.ts2009.com/mediaWiki/index.php/HowTo/Export_from_Blender#Exporter_Output

Как получится (или не получится) - здесь отпишусь :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Март 29, 2014, 11:30
Вот здесь написано, что Blender может в XML экспортировать: http://online.ts2009.com/mediaWiki/index.php/HowTo/Export_from_Blender#Exporter_Output
Насколько я помню, он может в 100500 форматов экспортировать + можно написать свои экспортеры.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Март 29, 2014, 11:36
Спасибо за инфу по поводу написания своих экспортёров! Может в будущем пригодиться. Меня обрадовало, что можно XML на деле применить :) Надо теперь пирамиду нарисовать в Blender'е и загрузить :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Март 29, 2014, 13:14
Я не понимаю, о чём идёт речь? :) Как я понял, Vertex у меня есть. Его можно сгенерировать программно, как в данном примере. А можно нарисовать фигуру в редакторе и загрузить Vertex из файла. Вы говорите о Vertex?
Вертексы - это точки, как минимум они должны иметь позицию. Но это далеко не все что они могут иметь, на одной позиции далеко не уедешь. Объект нужно освещать, текстурировать, поэтому обычно данных/атрибутов больше. Какие это атрибуты - разбирайтесь. Хранить все в виде массивов (как делает OpenGL) необязательно, напр в .obj файле это не так.

Сами точки еще не поверхность, поэтому нужны еще полигоны, обычно они хранят индексы вертексов, как правило от 1 до 4. Хотя OpenGL понимает полигоны и неявно (типа "каждые N вертексов образуют полигон")

Желание "нарисовать что-то крутое" вполне естественно :) Но увы, обычно на этом все и заканчивается. Ну загрузите, нарисуете, что с того? Задачи-то нет. OpenGL preview - это всего лишь мелкая деталь в 3D (причем худшая).


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 01, 2014, 12:10
Спасибо! Буду разбираться. Вот хороший туториал, в котором рассказано, как загрузить данные из obj-файла: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Load_OBJ


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 01, 2014, 14:55
Вот хороший туториал, в котором рассказано, как загрузить данные из obj-файла: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Load_OBJ
Ну как "хороший". Если с нуля - то да  :)

1) Автор ничего не говорит о строках начинающихся с "vt" и "vn" - а это самые важные данные модели

2) Автор получает вертексные нормали осредняя полигонные. Такой метод используется только в крайнем случае, когда ничего лучшего нет. Обычно осредненная нормаль заметно хуже аналитической, поэтому правильно читать нормали из obj файла, если они там есть. Да, и нормальная реализация осреднения гораздо сложнее чем у автора - напр нормали для куба
он вычислит некорректно

Хотя и по коду все видно, напр
Цитировать
   
if (line.substr(0,2) == "v ") {
  istringstream s(line.substr(2));
Во, управился :)  А если пробел перед "v"?

В общем Вика она Вика и есть. Да, можно много почерпнуть, спасибо ей. Но это не претендует ни на какое качество/глубину (о чем она сама честно предупреждает)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 01, 2014, 17:52
Спасибо! Правда про нормали пока ничего непонятно. Надеюсь, позже разберусь.

Как правильно парсить из ".obj"? Может для этих целей лучше применять регулярные выражения? Или это "выстрел из пушки по воробьям"?


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 01, 2014, 19:03
Как правильно парсить из ".obj"?
Как и любой текстовый формат: нужно помнить, что там могут быть любое количество пробелов, табуляций и переводов строк, причем в различных комбинациях. :)

Может для этих целей лучше применять регулярные выражения? Или это "выстрел из пушки по воробьям"?
Можно парсить все руками (формат очень прост), можно с регуляркой, а можно и boost::spirit прикрутить или lex/bison. :)
Но что-то мне подсказывает, что силы начинают растрачиваться во все стороны. :) Вы только начинаете, зачем вам идеальный загрузчик?
Вам сейчас нужно, что бы он загрузил вашу первую модель, с которой вы сможете экспериментировать. Когда он перестанет справляться, то вы его расширите/переделаете.
Поверьте, если вы будете делать идеальный контейнер с идеальным загрузчиком, до дело до решения собственно задачи не дойдет никогда. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 01, 2014, 19:17
Спасибо огромное за такие развёрнутые ответы! Буду парсить руками, а потом потихоньку прикручу регулярку :) За расширение кругозора отдельное спасибо :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: carrygun от Апрель 02, 2014, 04:22
boost::spirit

Это ему точно не нужно.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 02, 2014, 06:41
Это ему точно не нужно.
А кто решает что нужно ТС, а что нет? :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 02, 2014, 09:24
Как правильно парсить из ".obj"?
Да, минимизировать задачу, как правильно сказали выше. Если "по-взрослому" то там не одна неделя работы. И надо четко представлять структуры данных которые хотите получить.

Правда про нормали пока ничего непонятно. Надеюсь, позже разберусь.
В школе учили "производная" (дифференциал) и ее геометрический смысл


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 09, 2014, 08:54
Я решил отложить в сторону голову обезьяны: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Load_OBJ

Попробую сначала загрузить координаты вершин куба и массив индексов для треугольников (из которых состоит куб, как я понимаю).

Для начала написал создал класс с методом-заглушкой:
Parser.h
Код
C++ (Qt)
#ifndef PARSER_H
#define PARSER_H
 
#include <QList>
#include <QVector3D>
 
class Parser {
public:
   void parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes );
};
 
#endif // PARSER_H
 

Parser.cpp
Код
C++ (Qt)
#include "Parser.h"
 
void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) {
 
}
 

По умолчанию в Blender создаётся куб. Я экспортировал его в файл cube.obj:

cude.obj
Цитировать
# Blender v2.68 (sub 0) OBJ File: ''
# www.blender.org
o Cube
v 1.000000 1.000001 -0.999999
v 1.000000 -0.999999 -1.000001
v -1.000000 -0.999999 -1.000001
v -1.000000 1.000001 -0.999999
v 1.000000 0.999999 1.000001
v 0.999999 -1.000001 0.999999
v -1.000000 -1.000000 0.999999
v -1.000000 0.999999 1.000001
s off
f 1 2 4
f 5 8 6
f 1 5 2
f 2 6 3
f 3 7 4
f 5 1 8
f 2 3 4
f 8 7 6
f 5 6 2
f 6 7 3
f 7 8 4
f 1 4 8

Создал тест:
tst_CubeFromBlenderTests.cpp
Код
C++ (Qt)
#include <QString>
#include <QtTest>
#include "Parser.h"
#include <QVector3D>
 
class CubeFromBlenderTests : public QObject {
   Q_OBJECT
 
public:
   CubeFromBlenderTests( );
 
   static inline bool qFuzzyCompare( double p1, double p2, double delta ) {
       return ( qAbs( p1 - p2 ) <= delta * qMin( qAbs( p1 ), qAbs( p2 ) ));
   }
 
   private
Q_SLOTS:
   void testCase1_data( );
   void testCase1( );
};
 
CubeFromBlenderTests::CubeFromBlenderTests( ) {
}
 
void CubeFromBlenderTests::testCase1_data( ) {
   QTest::addColumn<QString>("input");
   QTest::addColumn<QList<QVector3D> >("expected_points");
   QTest::addColumn<QList<QVector3D> >("expected_indexes");
 
   QString input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n"
           "# www.blender.org\n"
           "o Cube\n"
           "v 1.000000 1.000001 -0.999999\n"
           "v 1.000000 -0.999999 -1.000001\n"
           "v -1.000000 -0.999999 -1.000001\n"
           "v -1.000000 1.000001 -0.999999\n"
           "v 1.000000 0.999999 1.000001\n"
           "v 0.999999 -1.000001 0.999999\n"
           "v -1.000000 -1.000000 0.999999\n"
           "v -1.000000 0.999999 1.000001\n"
           "s off\n"
           "f 1 2 4\n"
           "f 5 8 6\n"
           "f 1 5 2\n"
           "f 2 6 3\n"
           "f 3 7 4\n"
           "f 5 1 8\n"
           "f 2 3 4\n"
           "f 8 7 6\n"
           "f 5 6 2\n"
           "f 6 7 3\n"
           "f 7 8 4\n"
           "f 1 4 8\n" );
   QList<QVector3D> expected_points;
   QVector3D point;
 
   // 1
   point.setX( 1.000000 );
   point.setY( 1.000001 );
   point.setZ( -0.999999 );
   expected_points.append( point );
 
   // 2
   point.setX( 1.000000 );
   point.setY( -0.999999 );
   point.setZ( -1.000001 );
   expected_points.append( point );
 
   // 3
   point.setX( -1.000000 );
   point.setY( -0.999999 );
   point.setZ( -1.000001 );
   expected_points.append( point );
 
   // 4
   point.setX( -1.000000 );
   point.setY( 1.000001 );
   point.setZ( -0.999999 );
   expected_points.append( point );
 
   // 5
   point.setX( 1.000000 );
   point.setY( 0.999999 );
   point.setZ( 1.000001 );
   expected_points.append( point );
 
   // 6
   point.setX( 0.999999 );
   point.setY( -1.000001 );
   point.setZ( 0.999999 );
   expected_points.append( point );
 
   // 7
   point.setX( -1.000000 );
   point.setY( -1.000000 );
   point.setZ( 0.999999 );
   expected_points.append( point );
 
   // 8
   point.setX( -1.000000 );
   point.setY( 0.999999 );
   point.setZ( 1.000001 );
   expected_points.append( point );
 
   QList<QVector3D> expected_indexes;
   QVector3D indexes;
 
   // 1
   indexes.setX( 1.0 );
   indexes.setY( 2.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 2
   indexes.setX( 5.0 );
   indexes.setY( 8.0 );
   indexes.setZ( 6.0 );
   expected_indexes.append( indexes );
 
   // 3
   indexes.setX( 1.0 );
   indexes.setY( 5.0 );
   indexes.setZ( 2.0 );
   expected_indexes.append( indexes );
 
   // 4
   indexes.setX( 2.0 );
   indexes.setY( 6.0 );
   indexes.setZ( 3.0 );
   expected_indexes.append( indexes );
 
   // 5
   indexes.setX( 3.0 );
   indexes.setY( 7.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 6
   indexes.setX( 5.0 );
   indexes.setY( 1.0 );
   indexes.setZ( 8.0 );
   expected_indexes.append( indexes );
 
   // 7
   indexes.setX( 2.0 );
   indexes.setY( 3.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 8
   indexes.setX( 8.0 );
   indexes.setY( 7.0 );
   indexes.setZ( 6.0 );
   expected_indexes.append( indexes );
 
   // 9
   indexes.setX( 5.0 );
   indexes.setY( 6.0 );
   indexes.setZ( 2.0 );
   expected_indexes.append( indexes );
 
   // 10
   indexes.setX( 6.0 );
   indexes.setY( 7.0 );
   indexes.setZ( 3.0 );
   expected_indexes.append( indexes );
 
   // 11
   indexes.setX( 7.0 );
   indexes.setY( 8.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 12
   indexes.setX( 1.0 );
   indexes.setY( 4.0 );
   indexes.setZ( 8.0 );
   expected_indexes.append( indexes );
 
   QTest::newRow( "parseData_01" ) << input << expected_points << expected_indexes;
}
 
void CubeFromBlenderTests::testCase1( ) {
   QFETCH( QString, input );
   QFETCH( QList<QVector3D>, expected_points );
   QFETCH( QList<QVector3D>, expected_indexes );
 
   Parser parser;
   QList<QVector3D> points;
   QList<QVector3D> indexes;
   parser.parseData( input, points, indexes );
 
   double delta = 0.0001;
   bool result = false;
   QString msg;
 
   // Check size of points and indexes
   QCOMPARE( points.size( ), expected_points.size( ) );
   QCOMPARE( indexes.size( ), expected_indexes.size( ) );
 
   // Check points
   for ( std::size_t i = 0; i < points.size( ); ++i ) {
       // Check x
       result = qFuzzyCompare( points[i].x( ), expected_points[i].x( ), delta );
       msg = QString( "\nActual: %1"
               "\nExpected: %2"
               "\nDelta: %3" ).arg( points[i].x( ) ).arg( expected_points[i].x( ) ).arg( delta );
       QVERIFY2( result, msg.toStdString( ).c_str( ) );
 
       // Check y
       result = qFuzzyCompare( points[i].y( ), expected_points[i].y( ), delta );
       msg = QString( "\nActual: %1"
               "\nExpected: %2"
               "\nDelta: %3" ).arg( points[i].y( ) ).arg( expected_points[i].y( ) ).arg( delta );
       QVERIFY2( result, msg.toStdString( ).c_str( ) );
 
       // Check z
       result = qFuzzyCompare( points[i].z( ), expected_points[i].z( ), delta );
       msg = QString( "\nActual: %1"
               "\nExpected: %2"
               "\nDelta: %3" ).arg( points[i].z( ) ).arg( expected_points[i].z( ) ).arg( delta );
       QVERIFY2( result, msg.toStdString( ).c_str( ) );
   }
 
   // Check indexes
   int actualIndex = 0;
   int expectedIndex = 0;
   for ( std::size_t i = 0; i < indexes.size( ); ++i ) {
       // 1
       actualIndex = (int) indexes[i].x( );
       expectedIndex = (int) indexes[i].x( );
       QCOMPARE( actualIndex, expectedIndex );
 
       // 2
       actualIndex = (int) indexes[i].y( );
       expectedIndex = (int) indexes[i].y( );
       QCOMPARE( actualIndex, expectedIndex );
 
       // 3
       actualIndex = (int) indexes[i].z( );
       expectedIndex = (int) indexes[i].z( );
       QCOMPARE( actualIndex, expectedIndex );
   }
}
 
QTEST_APPLESS_MAIN( CubeFromBlenderTests )
 
#include "tst_CubeFromBlenderTests.moc"
 

Приступаю к реализации метода parseData().


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 09, 2014, 10:02
Вот такая получилась функция для парсинга и загрузги данных. Она справляется со своей задачей по-минимому. Возможно надо будет обработку ошибок включить. Буду рад любым замечаниям.

Parser.cpp
Код
C++ (Qt)
#include "Parser.h"
#include <QStringList>
 
void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) {
   QStringList list = input.split( "\n" );
 
   for ( std::size_t i = 0; i < list.size( ); ++i ) {
       // Poitns
       if ( list[i][0] == QChar( 'v' ) ) {
           QStringList listForPoints = list[i].split( " " );
           if ( listForPoints.size( ) == 4 ) {
               bool ok;
               float x = listForPoints[1].toFloat( &ok );
               if ( !ok ) {
                   break;
               }
 
               float y = listForPoints[2].toFloat( &ok );
               if ( !ok ) {
                   break;
               }
 
               float z = listForPoints[3].toFloat( &ok );
               if ( !ok ) {
                   break;
               }
 
               points.append( QVector3D( x, y, z ) );
           }
       }
 
       // Indexes
       if ( list[i][0] == QChar( 'f' ) ) {
           QStringList listForIndexes = list[i].split( " " );
           if ( listForIndexes.size( ) == 4 ) {
               bool ok;
               float x = listForIndexes[1].toFloat( &ok );
               if ( !ok ) {
                   break;
               }
 
               float y = listForIndexes[2].toFloat( &ok );
               if ( !ok ) {
                   break;
               }
 
               float z = listForIndexes[3].toFloat( &ok );
               if ( !ok ) {
                   break;
               }
 
               indexes.append( QVector3D( x, y, z ) );
           }
       }
   }
}
 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 09, 2014, 20:52
Вот такая получилась функция для парсинга и загрузги данных. Она справляется со своей задачей по-минимому. Возможно надо будет обработку ошибок включить. Буду рад любым замечаниям.
Приведенный код - халтура которая не заслуживает обсуждения/замечаний. Вот Вам простенький obj файл (аттач), тренируйтесь


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 09, 2014, 21:47
Вот, пришлось тоже недавно написать. Правда импортирую в свою структуру данных. Но это в коде понять можно, и при необхомости заменить.

Код
C++ (Qt)
#ifndef OBJFORMAT_H
#define OBJFORMAT_H
 
#include <QObject>
#include <QString>
#include <QVector>
#include <QFile>
#include <QStringList>
#include <QTextStream>
#include <QMessageBox>
#include <QInputDialog>
#include <QDir>
 
#include "simdynamic.h"
#include "./dialogs/importprogressdialog.h"
 
class ObjFormat : public QObject
{
   Q_OBJECT
 
public:
   explicit ObjFormat(QObject *parent = 0);
 
   void importModel(QString str, int digit);
   SimulationDynamicMesh* getModel(void){return simDynamicMesh;}
 
private:
   SimulationDynamicMesh* simDynamicMesh;
   QMessageBox msgBox;
   QFile       file;
 
   ImportProgressDialog* importProgressDlg;
 
   void parseLine(QString str);
 
   bool appVertex, appTexture, appFaces, appNormals;
 
signals:
 
public slots:
 
};
 
 

Код
C++ (Qt)
#include "objformat.h"
#include "common.h"
 
ObjFormat::ObjFormat(QObject *parent) :
   QObject(parent)
 , simDynamicMesh(new SimulationDynamicMesh())
 , appVertex(false)
 , appTexture(false)
 , appFaces(false)
 , appNormals(false)
{
}
 
void ObjFormat::importModel(QString str, int digit)
{
   importProgressDlg = new ImportProgressDialog();
   importProgressDlg->show();
 
   file.setFileName(str);
 
   if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
   {
       msgBox.setWindowTitle(SimError::critical);
       msgBox.setText(QString::fromLocal8Bit("File '") + str + QString::fromLocal8Bit("' wurde nicht gefunden!"));
       msgBox.setIcon(QMessageBox::Critical);
       msgBox.exec();
       return;
   }
 
   QTextStream stream(&file);
 
   importProgressDlg->printToLog("Parsing *obj File");
 
   QVector<QString> lines;
 
   while(!stream.atEnd())
   {
       lines.append(stream.readLine());
   }
   file.close();
 
   importProgressDlg->setProgressBarMaxValue(lines.size());
 
   for(int i = 0; i < lines.size(); i++)
   {
       parseLine(lines.at(i));
       importProgressDlg->setProgressBarValue(i);
   }
 
   if(!simDynamicMesh->haveIdenticalVertixes(importProgressDlg) && !simDynamicMesh->haveIdenticalFaces(importProgressDlg))
   {
       simDynamicMesh->sortEdges(importProgressDlg);
   }
 
   QString meshName = QString("Object_%1").arg(QString::number(digit));
   bool ok;
   QString text = QInputDialog::getText(NULL,tr("Simulation Object Name:"),tr("Simulation Object Name:"),QLineEdit::Normal,meshName,&ok);
    if (ok && !text.isEmpty())
        simDynamicMesh->setMeshName(text);
 
   importProgressDlg->close();
   delete importProgressDlg;
}
 
void ObjFormat::parseLine(QString str)
{
   str.remove("\t");
   str.remove("\n");
   str = str.trimmed();
 
   QStringList list = str.split(" ");
 
   if(list.at(0) == "v")  // parser vertex
   {
       simDynamicMesh->appendVertex(list.at(1).toFloat(), list.at(2).toFloat(), list.at(3).toFloat());
       simDynamicMesh->setLastVertexColor(0.75F, 0.75F, 0.75F);
       if(!appVertex)
       {
           importProgressDlg->printToLog("\tAppend Vertex Data");
           appVertex = true;
       }
   }
   else if(list.at(0) == "vn")
   {
       simDynamicMesh->appendNormals(list.at(1).toFloat(), list.at(2).toFloat(), list.at(3).toFloat());
       if(!appNormals)
       {
           importProgressDlg->printToLog("\tAppend Normal Data");
           appNormals = true;
       }
   }
   else if(list.at(0) == "vt")
   {
       simDynamicMesh->appendTexture(list.at(1).toFloat(), list.at(2).toFloat());
 
       if(!appTexture)
       {
           importProgressDlg->printToLog("\tAppend Texture Data");
           appTexture = true;
       }
   }
   else if(list.at(0) == "f")
   {
       QStringList vert1 = list.at(1).split("/");
       QStringList vert2 = list.at(2).split("/");
       QStringList vert3 = list.at(3).split("/");
 
       if(vert1.size() > 1)
       {
           simDynamicMesh->appendFace(vert1.at(0).toInt(), vert2.at(0).toInt(), vert3.at(0).toInt(),
                                      vert1.at(1).toInt(), vert2.at(1).toInt(), vert3.at(1).toInt(),
                                      vert1.at(2).toInt(), vert2.at(2).toInt(), vert3.at(2).toInt());
       }
       else
       {
           simDynamicMesh->appendFace(vert1.at(0).toInt(), vert2.at(0).toInt(), vert3.at(0).toInt());
       }
 
       if(!appFaces)
       {
           importProgressDlg->printToLog("\tAppend Face Data");
           appFaces = true;
       }
   }
}
 
 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 10, 2014, 09:23
Вот, пришлось тоже недавно написать. Правда импортирую в свою структуру данных. Но это в коде понять можно, и при необхомости заменить.
Ну вот, другое дело - видно что человек работал, задачу решал (а не прыгал туда-сюда "по всему интересному"). Замечания

- фейсет может иметь ссылаться на любое число вертексов (напр 1, 2 или 1000)

- позиции всегда есть, но нормали, и UV могут быть или нет  (f 33//41 ..) или (f  33/21 ..). Также атрибуты не обязаны сбиваться, напр одна фейсет может иметь UV но другая нет.

- файл может содержать любое число объектов, (но нумерация вертексов одна)

- мелочи: индексы могут быть отрицательными, строки могут склеиваться слешем "\"

Это в игровых моделях всегда треугольники и всегда 3 атрибута, в общем случае это не так. Более сложные вещи (импорт материала, декомпозиция по материалу, разбивка complex полигонов и др) не рассматриваем, речь о простом парсере. Ну и конечно "split" загнется уже на среднем объеме, ну то тоже ладно, то уже профессиональный парсер, за рамками темы


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 10, 2014, 12:15
Спасибо, Игорь за замечания.
У меня была очень  ограниченная задача. Все модели на входе имели только трианглы, поэтому не стал писать универсальную версию. Но на счет орицательных индексов и обратного слеша - не знал. Спасибо за инфу.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: m_ax от Апрель 10, 2014, 12:35
Ну вот, другое дело - видно что человек работал, задачу решал (а не прыгал туда-сюда "по всему интересному").
А что в итоге получилось? :-\
Какая то невообразимая архитектурная каша.. Один чих и всё развалится(


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 12:43
Ну вот, другое дело - видно что человек работал, задачу решал (а не прыгал туда-сюда "по всему интересному").
Расскажите пожалуйста о киллер фичах второго решения по сравнению с первым.
Чем оно вам так понравилось? Правильно я понимаю, что у вас примерно также, только еще материалы читает?


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 10, 2014, 12:52
А что в итоге получилось? :-\
Какая то невообразимая архитектурная каша.. Один чих и всё развалится(

Почему каша, и какой именно "чих" все это развалит? Обоснуйте.

Под "чихом", я так понимаю, подразумевается какой-нибудь безпорядочно написаный *obj файл. Так, я уже сделал замечание, что парсер читает только выхлоп из одного редактора и не предполагает универсальности. 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 10, 2014, 15:48
Расскажите пожалуйста о киллер фичах второго решения по сравнению с первым.
В нем выделена "сущность" (класс модели) и вызываются его методы, это нормально. А Ваш протеже действовал в худших традициях процедурного программирования
Код
C++ (Qt)
void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes )
 
Да еще контейнеры подобраны - полный ппц. Потому что голова занята не делом а "всякой всячиной"


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 15:59
В нем выделена "сущность" (класс модели) и вызываются его методы, это нормально.
Еще раз спрошу, вас сам загрузчик радует?

А Ваш протеже действовал в худших традициях процедурного программирования
Мой протеже? Это когда он стал моим протеже, когда перестал слушать ваши дурные советы? :)
На сколько я вижу, 8Observer8 воспользовался моим советом (который вы кстати тоже поддержали), и написал наколенную поделку для загрузки модели из obj файла, что бы уже начать саму работу с opengl. Что в этом плохого?

Да еще контейнеры подобраны - полный ппц. Потому что голова занята не делом а "всякой всячиной"
Да, здесь он "промахнулся", он должен был использовать QVector, т.к вы везде используете QVector. простите его, он просто этого не знал. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 10, 2014, 16:52
Еще раз спрошу, вас сам загрузчик радует?
А почему он должен меня "радовать" или "огорчать"? :) Для "наколенной поделки" - вполне, а об остальном речи не было.

На сколько я вижу, 8Observer8 воспользовался моим советом (который вы кстати тоже поддержали), и написал наколенную поделку для загрузки модели из obj файла, что бы уже начать саму работу с opengl. Что в этом плохого?
Вот и расскажите как в OpenGL воспользоваться тем что прочитал 8Observer8


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 17:02
А почему он должен меня "радовать" или "огорчать"? :) Для "наколенной поделки" - вполне, а об остальном речи не было.
Я про расхваленный вами вариант Hrundel. :)
Вы похвалить похвалили, а за что непонятно. Будьте любезны.

Вот и расскажите как в OpenGL воспользоваться тем что прочитал 8Observer8
А вот вам чуть позже 8Observer8 и покажет. А если у него не получиться, то расскажу я. Хотя уже лет 10 к opengl не подходил. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 10, 2014, 18:00
Я про расхваленный вами вариант Hrundel. :)
Вы похвалить похвалили, а за что непонятно. Будьте любезны.
Я уже Вам ответил
Цитата: Igors link=topic=26752.msg193429#msg193429
В нем выделена "сущность" (класс модели) и вызываются его методы, это нормально.
То есть принципиально подход верный, дальше можно наращивать парсер (если надо). То что замусорено печатью лога - дело житейское. А в др варианте налицо непонимание ООП и программирования вообще. И, что мне особенно не нравится, очень поверхностное отношение к задаче. Интенсивное изучение теории этого не компенсирует.

А вот вам чуть позже 8Observer8 и покажет. А если у него не получиться, то расскажу я. Хотя уже лет 10 к opengl не подходил. :)
Трудновато будет рассказать то чего нет :) Данные obj файла с opengl несовместимы - или рисовать по фейсетам (совсем бедно) или конвертировать.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 18:09
То есть принципиально подход верный, дальше можно наращивать парсер (если надо). То что замусорено печатью лога - дело житейское.
А в чем верность подхода? В том, что один класс и данные читает и прогресс показывает?

А в др варианте налицо непонимание ООП и программирования вообще.
Да вы что, и программирования вообще? :)
Это все из-за вашего непонимания программирования, ну а про ООП и не говорю. :)

И, что мне особенно не нравится, очень поверхностное отношение к задаче.
Всем наплевать.

Интенсивное изучение теории этого не компенсирует.
Конечно, поэтому он и пишет код.

Данные obj файла с opengl несовместимы
Ну да, ну да.  ::)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 10, 2014, 18:27
Мне теперь неудобно что-либо говорить, но о понимаии ООП мы уже дискутировали один раз и 8Observer8 действительно не полностью понимает его значения. Точнее говоря, просто знаний не хватает.

Я про расхваленный вами вариант Hrundel. :)
Вы похвалить похвалили, а за что непонятно. Будьте любезны.

А почему бы меня и не похвалить. Я изо всех сил стремлюсь к структурированному программированию как Дийкстра когда-то  ;D
И, кстати, я своим парсером читаю вот такие модельки очень даже успешно.



Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 10, 2014, 18:41
А в чем верность подхода? В том, что один класс и данные читает и прогресс показывает?
Не один, прогресс включен агрегатом, вполне норм. Др дело от выводимых сообщений толку маловато (проще действовать по размеру прочитанного), но то уже постановка.

Ну да, ну да.  ::)
Какой-то Вы "наивный" или "непрактичный" - не знаю как сказать :) Полигонной геометрией я занимаюсь давненько, а Вы так, "чуть слышали". Чего лезть "с грыжей на танк"?  :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 10, 2014, 19:03
У меня проблема с рисованием куба. Он не рисуется.

Я так понимаю, что рисовать надо с помощью функций:
Код
C++ (Qt)
void Scene::draw()
{
   // указываем, откуда нужно извлечь данные о массиве вершин
   glVertexPointer(3, GL_FLOAT, 0, m_vertexArray);
   // указываем, откуда нужно извлечь данные о массиве цветов вершин
   glColorPointer(3, GL_FLOAT, 0, m_colorArray);
   // используя массивы вершин и индексов, строим поверхности
   glDrawElements(GL_TRIANGLES, m_sizeOfIndexesArray * 3, GL_UNSIGNED_BYTE, m_indexArray);
}
 

Далее будет очень черновой код. Мне главное идею понять, правильно ли я делаю? В следующей функции я заполняю три массива: m_vertexArray, m_colorArray, m_indexArray:
Код
C++ (Qt)
void Scene::setPointsAndIndexes(QList<QVector3D> &points, QList<QVector3D> &indexes)
{
   // Points
   m_sizeOfpointsArray = points.size();
   m_vertexArray = new GLfloat*[m_sizeOfpointsArray];
   const int amountOfCoordinates = 3;
   for (int i = 0; i < m_sizeOfpointsArray; i++) {
       m_vertexArray[i] = new GLfloat[amountOfCoordinates];
   }
 
   for (int row = 0; row < m_sizeOfpointsArray; ++row) {
       int col = 0;
       m_vertexArray[row][col++] = points[row].x();
       m_vertexArray[row][col++] = points[row].y();
       m_vertexArray[row][col] = points[row].z();
   }
 
//    for (int row = 0; row < m_sizeOfpointsArray; ++row) {
//        for (int col = 0; col < amountOfCoordinates; ++col) {
//            qDebug() << m_vertexArray[row][col];
//        }
//    }
 
   // Indexes
   m_sizeOfIndexesArray = indexes.size();
   m_indexArray = new GLfloat*[m_sizeOfIndexesArray];
   for (int i = 0; i < m_sizeOfIndexesArray; i++) {
       m_indexArray[i] = new GLfloat[amountOfCoordinates];
   }
 
   for (int row = 0; row < m_sizeOfIndexesArray; ++row) {
       int col = 0;
       m_indexArray[row][col++] = indexes[row].x();
       m_indexArray[row][col++] = indexes[row].y();
       m_indexArray[row][col] = indexes[row].z();
   }
 
//    for (int row = 0; row < m_sizeOfIndexesArray; ++row) {
//        for (int col = 0; col < amountOfCoordinates; ++col) {
//            qDebug() << m_indexArray[row][col];
//        }
//    }
 
   // Colors
   m_colorArray = new GLfloat*[m_sizeOfpointsArray];
   for (int i = 0; i < m_sizeOfpointsArray; i++) {
       m_colorArray[i] = new GLfloat[amountOfCoordinates];
   }
 
   for (int row = 0; row < m_sizeOfpointsArray; ++row) {
       int col = 0;
       m_colorArray[row][col++] = 0.1f*( qrand()%11 ); // R - красная составляющая
       m_colorArray[row][col++] = 0.1f*( qrand()%11 ); // G - зелёная составляющая
       m_colorArray[row][col] = 0.1f*( qrand()%11 ); // B - синяя составляющая
       // qDebug() << m_colorArray[row][0] << " " << m_colorArray[row][1] << " " << m_colorArray[row][2];
       // qrand()%11 - псевдослучайное число от 0 до 10
   }
 
   draw();
}

Вот что в файле хранится:
Цитировать
# Blender v2.68 (sub 0) OBJ File: ''
# www.blender.org
o Cube
v 1.000000 1.000001 -0.999999
v 1.000000 -0.999999 -1.000001
v -1.000000 -0.999999 -1.000001
v -1.000000 1.000001 -0.999999
v 1.000000 0.999999 1.000001
v 0.999999 -1.000001 0.999999
v -1.000000 -1.000000 0.999999
v -1.000000 0.999999 1.000001
s off
f 1 2 4
f 5 8 6
f 1 5 2
f 2 6 3
f 3 7 4
f 5 1 8
f 2 3 4
f 8 7 6
f 5 6 2
f 6 7 3
f 7 8 4
f 1 4 8


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 19:12
А почему бы меня и не похвалить. Я изо всех сил стремлюсь к структурированному программированию как Дийкстра когда-то  ;D
Нужно либо вас обоих хвалить, либо обоих ругать. ;)

И, кстати, я своим парсером читаю вот такие модельки очень даже успешно.
Парсер 8Observer8 так-же успешно его прочтет. Они у вас практически одинаковые. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 19:14
Не один, прогресс включен агрегатом, вполне норм.
Для вас это норм? Я уже не удивляюсь. Т.е. без GUI я файл загрузить не смогу?
А вот был бы там сигнал (или возможность подключить наблюдателя), информирующий о прогрессе, было бы хорошо.

Чего лезть "с грыжей на танк"?  :)
Ась. Не вижу танка. :)
Вы за мои знания не переживайте, вы о своих подумайте. Если бы вы были в этом специалистом, то не писали бы ерунду.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 19:30
У меня проблема с рисованием куба. Он не рисуется.
Попробуйте сначала одну грань (или треугольник) нарисовать. Руками задайте данные, просто что бы нарисовало.
В интернетах кучи документации и маленьких демок, вы спотыкаетесь на каждой ерунде. :(


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 10, 2014, 19:34
Спасибо! Что-то я об этом не подумал... :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 10, 2014, 20:10
2 Hrundel У вас в коде ошибка, течет память и оставляет видимым диалог прогресса, если файл нельзя открыть.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 10, 2014, 20:53
2 Hrundel У вас в коде ошибка, течет память и оставляет видимым диалог прогресса, если файл нельзя открыть.

Это может быть - иногда испытываю затруднения с указателями.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 10, 2014, 22:38
Я немного продвинулся вперёд. Мне удалось нарисовать треугольник:

(http://i.pixs.ru/storage/5/1/5/165png_2377040_11636515.png)

Ещё я из следующего примера добавил: оси, поворот с помощью мыши, приближение и отдаление с помощью колёсика мыши: http://www.gamedev.ru/code/articles/OpenGL_Qt4 (http://www.gamedev.ru/code/articles/OpenGL_Qt4)

Код: https://github.com/8Observer8/CubeFromBlender/tree/one_triangle (https://github.com/8Observer8/CubeFromBlender/tree/one_triangle)

Подскажите, пожалуйста, как узнать в Blender какой вершине соответствует какой индекс?


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: m_ax от Апрель 11, 2014, 08:52
А что в итоге получилось? :-\
Какая то невообразимая архитектурная каша.. Один чих и всё развалится(

Почему каша, и какой именно "чих" все это развалит? Обоснуйте.

Под "чихом", я так понимаю, подразумевается какой-нибудь безпорядочно написаный *obj файл. Так, я уже сделал замечание, что парсер читает только выхлоп из одного редактора и не предполагает универсальности. 
Чих - это не только файл..

Во-первых, ваш "парсер" слишком много знает.. Он сильно завязан на гуи, хотя парсер вообще не должен знать об этом ни-че-го.. Такая архитектура вообще противоречит принципам ООП, раз уж тут об этом речь зашла.. Если измениться интерфейс прогрессдиалога или сам прогрессдиалог, то придётся лезть под капот этого парсера.. 

Во-вторых сама реализация парсера.. мм.. не самая изящная.. 
   


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 11, 2014, 09:36
Далее будет очень черновой код. Мне главное идею понять, правильно ли я делаю? В следующей функции я заполняю три массива: m_vertexArray, m_colorArray, m_indexArray:
Код
C++ (Qt)
void Scene::setPointsAndIndexes(QList<QVector3D> &points, QList<QVector3D> &indexes)
 
А кто Вам мешал заполнить все три массива сразу при чтении obj файла? И почему Scene планируется в расчете только на 1 объект? Их может быть и больше. Куда Вы все время летите, почему все тяп-ляп? Разберемся c glDrawElements

Цитировать
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices);

1-й аргумент - что рисуем, какие примитивы - у нас треугольники
2-й аргумент  - сколько треугольников
3-й аргумент  - сколько байт на индекс, чего ж GL_UNSIGNED_BYTE, индекс может ссылаться на вертекс напр 10000. Конечно GL_UNSIGNED_INT
4-й аргумент - массив int'ов (указатель)

В obj файле
Цитировать
f 1 2 4
f 5 8 6
f 1 5 2
...
Значит подаваемый массив { 1 2 4 5 8 6 1 5 2.. }

Теперь с glVertexPointer(3, GL_FLOAT, 0, m_vertexArray);
В obj файле
Цитировать
v 1.000000 1.000001 -0.999999
v 1.000000 -0.999999 -1.000001
v -1.000000 -0.999999 -1.000001...
Значит подаваемый массив
{ 1.000000 1.000001 -0.999999
   1.000000 -0.999999 -1.000001
 -1.000000 -0.999999 -1.000001...
}



Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 11, 2014, 09:56
Во-первых, ваш "парсер" слишком много знает.. Он сильно завязан на гуи, хотя парсер вообще не должен знать об этом ни-че-го.. Такая архитектура вообще противоречит принципам ООП, раз уж тут об этом речь зашла.. Если измениться интерфейс прогрессдиалога или сам прогрессдиалог, то придётся лезть под капот этого парсера.. 
Не вижу где он "завязан" на UI, ну может QMessageBox. А так нормально, юзается интерфейс прогрессдиалога, в кишки не влазим. И, зная Вас, убежден что никакого feedback'а в Вашей реализации не случилось бы вообще - ушли бы гулять с собачкой, и все  :)

Во-вторых сама реализация парсера.. мм.. не самая изящная.. 
Так никто ж не мешает показать "более изящную", богатырскую силу буста и освоившего его программиста  :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 10:07
А кто Вам мешал заполнить все три массива сразу при чтении obj файла?
А почему он должен был их сразу заполнять?
Здесь он получает исключительно данные из файла, дальше он их может разложить в какие угодно специализированные структуры.

И почему Scene планируется в расчете только на 1 объект? Их может быть и больше.
Потому что он скопипастил его из примера, он там даже ссылку на него привел.

чего ж GL_UNSIGNED_BYTE, индекс может ссылаться на вертекс напр 10000. Конечно GL_UNSIGNED_INT
А почему нет, у нас всего 8 вершин, байта хватит с головой.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 10:11
Не вижу где он "завязан" на UI, ну может QMessageBox.
И QInputDialog? :)

А так нормально
Сойдет.

Так никто ж не мешает показать "более изящную", богатырскую силу буста и освоившего его программиста  :)
Точно-точно, у вас же есть готовая, так сказать "профессиональная" - покажите.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 11, 2014, 10:52
Точно-точно, у вас же есть готовая, так сказать "профессиональная" - покажите.
Ну вот, то обзываете меня всяко - то "покажите" :). Нет уж, да и не смог бы, это был заказ.

А вот где ж ота вся умность std/boost которой некоторые так гордятся? Формат легкий и приятный, есть куда более гнусные. Следовало ожидать что вот "щас", "на раз" - но ничего не происходит. Ну где же Ваши "карандаши" которые так усердно затачивались? А если дойдет до дела - опять позорный split, или как?  :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 11:02
Ну вот, то обзываете меня всяко - то "покажите" :). Нет уж, да и не смог бы, это был заказ.
Другого ответа я и не ждал. Все как всегда. Зато написать "халтура" это вы первый. :)

А вот где ж ота вся умность std/boost которой некоторые так гордятся? Формат легкий и приятный, есть куда более гнусные. Следовало ожидать что вот "щас", "на раз" - но ничего не происходит. Ну где же Ваши "карандаши" которые так усердно затачивались?
Карандаши там же где и у вас. :)
С той лишь разницей, что нам читать этот формат и даром не надо, а вы как бы должны, ведь вы же
Полигонной геометрией я занимаюсь давненько...
:)

А если дойдет до дела - опять позорный split, или как?  :)
Нет, будет boost::spirit.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 11, 2014, 11:30
Во-первых, ваш "парсер" слишком много знает.. Он сильно завязан на гуи, хотя парсер вообще не должен знать об этом ни-че-го.. Такая архитектура вообще противоречит принципам ООП, раз уж тут об этом речь зашла.. Если измениться интерфейс прогрессдиалога или сам прогрессдиалог, то придётся лезть под капот этого парсера.. 
Не вижу где он "завязан" на UI, ну может QMessageBox. А так нормально, юзается интерфейс прогрессдиалога, в кишки не влазим. И, зная Вас, убежден что никакого feedback'а в Вашей реализации не случилось бы вообще - ушли бы гулять с собачкой, и все  :)

Во-вторых сама реализация парсера.. мм.. не самая изящная.. 
Так никто ж не мешает показать "более изящную", богатырскую силу буста и освоившего его программиста  :)

Спасибо, Игорь, мне уже и добавить нечего  ;D ;D ;D

Что касается "завязки" на GUI - ну знаете, я все-таки семестровый проект пишу, а не корпаративный продукт от Adobe. Строгой независимости классов с меня никто не требует. 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: m_ax от Апрель 11, 2014, 11:42
Во-первых, ваш "парсер" слишком много знает.. Он сильно завязан на гуи, хотя парсер вообще не должен знать об этом ни-че-го.. Такая архитектура вообще противоречит принципам ООП, раз уж тут об этом речь зашла.. Если измениться интерфейс прогрессдиалога или сам прогрессдиалог, то придётся лезть под капот этого парсера.. 
Не вижу где он "завязан" на UI, ну может QMessageBox. А так нормально, юзается интерфейс прогрессдиалога, в кишки не влазим. И, зная Вас, убежден что никакого feedback'а в Вашей реализации не случилось бы вообще - ушли бы гулять с собачкой, и все  :)

Во-вторых сама реализация парсера.. мм.. не самая изящная.. 
Так никто ж не мешает показать "более изящную", богатырскую силу буста и освоившего его программиста  :)

Спасибо, Игорь, мне уже и добавить нечего  ;D ;D ;D

Что касается "завязки" на GUI - ну знаете, я все-таки семестровый проект пишу, а не корпаративный продукт от Adobe. Строгой независимости классов с меня никто не требует. 

Дело не только в завязке на гуи.. (хотя это уже о многом говорит)
Сама реализация парсера в аля процедурном стиле(
Да и использование сплита.. где то я это уже видел)   


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 11:44
Что касается "завязки" на GUI - ну знаете, я все-таки семестровый проект пишу, а не корпаративный продукт от Adobe. Строгой независимости классов с меня никто не требует.  
Не обижайтесь, я нисколько не хочу принизить ваш код.
Просто мне было непонятно, откуда такая избирательност, почему наш "профессионал" хвалит одного и ругает другого? Хотя и у вас и у 8Observer8, есть что поругать, и что похвалить. :)
Сейчас я понимаю, что 8Observer8 "в опале" за то, что не внемлет "профессионалу". И главное он может не переживать дальше: все что он будет делать - будет называться халтурой. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 11, 2014, 12:19
Не обижайтесь, я нисколько не хочу принизить ваш код.
Просто мне было непонятно, откуда такая избирательност, почему наш "профессионал" хвалит одного и ругает другого? Хотя и у вас и у 8Observer8, есть что поругать, и что похвалить. :)

Да я и не обижаюсь совсем  :) Я на великое не претендую. Я, ведь, еще учусь!

Ну, на счет Игоря, могу сказать, что он как-то помог написать мне кусок кода. Мне было все очень понятно. Его стиль мне нравиться. Это наверное как в искусстве - кто-то импрессионистично картины пишет, кто-то академично. И то, и другое имеет место быть. Рамок быть не должно - иначе не будет открытий. А правила, конечно, соблюдать надо. Без граммотности красота не возможна.

Давайте лучше переключимся на ТС. Что-то он не отвечает больше. Получается у него там парсеную модельку показать?

Да, и мнение M_AX по коду ТС, тоже было бы интересно выслушать.

А по поводу сплита я как-то не понимаю. Для всего есть свой инструмент. Вилкой суп есть не будешь. Сплит прост и удобен. Ошибок в его работе вроде как не замечено.

На счет парсера в "аля процедурном стиле" тоже не понял. Может быть какой-то другой стиль в подходе к парсеру? И он действительно необходим?
Тогда, прошу привести пример кода. А то, как-то, M_AX голословно все у вас.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: OKTA от Апрель 11, 2014, 14:04
Мне кажется, что Old и Igors давно уже должны устроить ООП-баттл  ;D


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 14:24
Пока из файла построить не получается. Не разоблался в соответсвии между порядком координат и индексов в массивах.

Вот кубик, который задаётся в самой программе:

(http://i.pixs.ru/storage/4/2/7/166png_8999474_11643427.png)

Исходники: https://github.com/8Observer8/Cube (https://github.com/8Observer8/Cube)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 11, 2014, 16:16
Хотя и у вас и у 8Observer8, есть что поругать, и что похвалить. :)
А Вы можете компетентно ругать/хвалить? Думаю что нет, т.к. понятия не имеете что такое "vn", "vt", каковы их роли и как они используются. Пренебрежение к предметной части всегда было и будет уязвимым местом начитанных умников, а если еще и не хватает ума это скрыть - люди и жизнь будут тыкать их носом часто и охотно  :)

Хвалить 8Observer8 совершенно не за что, а ярлык "халтурщик" он заслужил 100%. Модель имеющая только позиции вертексов никому не нужна, бесполезна, о чем ему было прекрасно известно. Тем не менее в очередной раз он решил еще "упростить" задачу для себя. "Ну это же для примера", какая разница? Да вот в том-то и дело что все настолько упрощено, что давно уже потеряло всякий смысл - нет задачи, работы, цели, вместо этого совершенно бестолковое поглощение optional информации. Не блоги надо вести, а программировать учиться.

Давайте лучше переключимся на ТС. Что-то он не отвечает больше. Получается у него там  по поводу сплита я как-то не понимаю. Для всего есть свой инструмент. Вилкой суп есть не будешь. Сплит прост и удобен. Ошибок в его работе вроде как не замечено.
Obj файл может быть очень больших размеров. Одним из требований моего заказчика была скорость (предыдущий парсер читал файл 2Gb несколько часов). А за удобство split приходится платить скоростью


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 16:25
То что я лентяй и халтурщик - это я и без Вас знаю :)

Я читал у Шлее, что split быстрее, чем RegExp. Если файл большой, то можно читать блоками и делать split.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 16:27
т.к. понятия не имеете что такое "vn", "vt", каковы их роли и как они используются.
Вы про нормали и текстурные координаты? :)
Это только для вас является сакральными знаниями (на ряду с матрицами), все остальные про эти "знания" даже не заикаются, это уровень детского сада. :)

Хвалить 8Observer8 совершенно не за что, а ярлык "халтурщик" он заслужил 100%.
Вовсе нет, он начинающий. :)

м
Модель имеющая только позиции вертексов никому не нужна, бесполезна, о чем ему было прекрасно известно.
Это вам она может не нужна. А ему на данном этапе изучения вполне достаточна.

Тем не менее в очередной раз он решил еще "упростить" задачу для себя.
А что вам с того? Что вас так заводит? ;)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 16:44
На счет парсера в "аля процедурном стиле" тоже не понял. Может быть какой-то другой стиль в подходе к парсеру? И он действительно необходим?
Что значит действительно необходим? Как мы будем решать, действительно или не действительно, он необходим? :)
Вопрос адресован m_ax, давайте подождем его ответа, а потом я вам расскажу как я вижу ОО-подход при решении этой задачи. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 11, 2014, 16:49
Вы про нормали и текстурные координаты? :)
Это только для вас является сакральными знаниями (на ряду с матрицами), все остальные про эти "знания" даже не заикаются, это уровень детского сада. :)
Если бы Вы хоть раз сами их рассчитали - Вы бы застрелили на месте того кто посмел их не прочитать :) Но судя по "детскому саду" Вам этого делать не приходилось. И я прекрасно понимаю почему Вы симпатизируете 8Observer8 - это же Ваша копия. Знать все-все, и все поверхностно. Так, слышал, просмотрел - и хватит.

А что вам с того? Что вас так заводит? ;)
Ну это как бы тема "властелина колец" из детской сказки. Человек показал очень энергичный, деловой (в хорошем смысле этого слова) подход. Чего скрывать, за неск недель освоил то на что у других уходят годы. Но все-таки это не программист. Нет элемента философии (не побоюсь этого слова), нет склонности и желания докопаться, вникнуть, упереться рогом, всегда пойдет по пути наименьшего сопротивления. Поэтому огромная мощь кольца не может быть использована на благие цели. А что с кольцом делать - см фильм (лучше с гоблинским переводом :)).

Это все, умолкаю.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 17:03
Если бы Вы хоть раз сами их рассчитали - Вы бы застрелили на месте того кто посмел их не прочитать :)  Но судя по "детскому саду" Вам этого делать не приходилось.
Ну конечно, их рассчитывали только вы? Вы же гений 3D. Куда там другим до вас....  ;D

Знать все-все, и все поверхностно.
Это лучше, чем не знать ничего, как вы. :) Зато важно раздувать щеки и рассказывать про финдреплейсы вы первый. Просто ничего сложнее вы сделать не в состоянии. :)
Поэтому, роль "великого учителя" на этом форуме для вас так важна, и именно поэтому вы так заводитесь, если кто-то не выполняет ваши "рекомендации". :)
Да ради Бога, вы самый великий профессионал во вселенной. :) Все равно знаний у вас от этого не появиться. Пшик.

Нет элемента философии (не побоюсь этого слова), нет склонности и желания докопаться, вникнуть, упереться рогом, всегда пойдет по пути наименьшего сопротивления.
Для того что бы он докапывался, ему нужна интересная тема. Не полигоны рисовать и не деревья фигур выводить. ;)
Когда он найдет себе задачу, он будет и рыть и копать.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 19:06
Объясню подробно свой затык. Надеюсь на помощь.

Когда я в коде создаю массив индексов, то руководствуюсь таким принципом - обход по индексам треугольников должен быть по часовой стрелке.

Я на листочке нарисовал куб. Произвольно расставил порядковые номера вершин:

(http://i6.pixs.ru/storage/6/5/2/167png_7809954_11648652.png)

(http://i6.pixs.ru/storage/6/6/5/168png_4076843_11648665.png)

Исходя из рисунков выше создал массив для всех треугольников (их 12):
Код
C++ (Qt)
   // Top
   IndexArray[0][0]=0;
   IndexArray[0][1]=1;
   IndexArray[0][2]=2;
 
   IndexArray[1][0]=2;
   IndexArray[1][1]=3;
   IndexArray[1][2]=0;
 
   // Bottom
   IndexArray[2][0]=4;
   IndexArray[2][1]=7;
   IndexArray[2][2]=5;
 
   IndexArray[3][0]=5;
   IndexArray[3][1]=7;
   IndexArray[3][2]=6;
 
   // Sides
   IndexArray[4][0]=0;
   IndexArray[4][1]=4;
   IndexArray[4][2]=5;
 
   IndexArray[5][0]=0;
   IndexArray[5][1]=5;
   IndexArray[5][2]=1;
 
   IndexArray[6][0]=1;
   IndexArray[6][1]=5;
   IndexArray[6][2]=2;
 
   IndexArray[7][0]=2;
   IndexArray[7][1]=5;
   IndexArray[7][2]=6;
 
   IndexArray[8][0]=2;
   IndexArray[8][1]=6;
   IndexArray[8][2]=3;
 
   IndexArray[9][0]=3;
   IndexArray[9][1]=6;
   IndexArray[9][2]=7;
 
   IndexArray[10][0]=0;
   IndexArray[10][1]=3;
   IndexArray[10][2]=7;
 
   IndexArray[11][0]=0;
   IndexArray[11][1]=7;
   IndexArray[11][2]=4;
 

А вот как быть с индексами, которые генерирует Blender?
Цитировать
f 8 7 6
f 3 2 6
f 5 8 6
f 4 3 8
f 8 5 1
f 5 6 2
f 3 7 8
f 1 2 4
f 1 5 2
f 4 8 1
f 7 3 6
f 2 3 4

Он почему-то не с нуля начинает. Ну ладно, можно отнять единицу:
Цитировать
f 7 6 5
f 2 1 5
f 4 7 5
f 3 2 7
f 7 4 0
f 4 5 2
f 2 6 7
f 0 1 3
f 0 4 1
f 3 7 0
f 6 2 5
f 1 2 3

Я как не игрался, но так и не смог правильно расставить индексы вершин треугольников, чтобы совпало с массивом выше:

(http://i6.pixs.ru/storage/6/0/4/169png_8919954_11648604.png)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 19:09
Добавил индексы на рисунки.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 19:57
Нашёл Add-on, который позволяет показать индексы: http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Index_Visualiser


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 11, 2014, 20:03
Вот я вам отправляю ваш проект, надеюсь в последний раз. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 20:09
Спасибо огромное! :)

Я проанализирую Ваши изменения в проекте и опишу свои ошибки здесь позже :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 11, 2014, 23:21
Для начала: оси не выглядывают. Скорее всего, из-за того, что судя по индексам, обход по треугольнику совершается против часовой стрелки, поэтому нормали смотрят внутрь. Хотя с другой стороны, я думал, что нормаль определяет с какой стороны будет прозрачность. Если внутрь куба прокрутить, то там нет прозрачности граней. Короче, у меня каша в голове :) Надеюсь, постепенно разберусь хотя бы в этих начальных вещах :)

Ещё эта опция почему-то не влияет ни на что:
Код
C++ (Qt)
glEnable(GL_CULL_FACE); // устанавливаем режим, когда строятся только внешние поверхности
 
Пробовал закомментировать - ничего не происходит.

С аддоном теперь намного лучше:
(http://i.pixs.ru/storage/9/4/8/170png_4868115_11652948.png)

Ошибки и изменения позже проанализирую. Эту тему можно будет закончить, когда голову обезьяны смогу загрузить :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: m_ax от Апрель 11, 2014, 23:58

А по поводу сплита я как-то не понимаю. Для всего есть свой инструмент. Вилкой суп есть не будешь. Сплит прост и удобен. Ошибок в его работе вроде как не замечено.

На счет парсера в "аля процедурном стиле" тоже не понял. Может быть какой-то другой стиль в подходе к парсеру? И он действительно необходим?
Тогда, прошу привести пример кода. А то, как-то, M_AX голословно все у вас.
Из того, что сплит для Вас прост и удобен, ещё не следует, что он в этой задаче - оптимальное решение.. И, кстатии, ошибок в работе своего молотка я тоже пока не замечал, но это не значит, что его нужно использовать для решения проблем, которые под руку попадутся..)  

По-поводу процедурного стиля.. Наверное правильнее было сказать - процедурный подход решения проблемы..
Достаточно взглянуть на метод parseLine..
Я понимаю, конечно, что формат obj Вам упрощает задачу, и число этих if else if else по пальцам пересчитать, но что если чуть усложнить формат.. Вас бы не смутило, что этих if else if else стало бы стопятьсот? И всё это в одном методе..

Потом этот парсер выкинет вам исключение out of range, если чуть подпортить obj файл.. И пользователь вашего парсера не сможет его адекватно обработать.. Он даже не будет в курсе что произошло.. и как с этим дальше жить(
Но Вас, конечно, такие мелочи не беспокоят.. работает и ладно..




  


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 12, 2014, 07:04
Я понимаю, конечно, что формат obj Вам упрощает задачу, и число этих if else if else по пальцам пересчитать, но что если чуть усложнить формат..
Если посмотреть спецификацию на этот формат, то не все так радужно: http://www.martinreddy.net/gfx/3d/OBJ.spec :)
И если понадобится полноценная поддержка, то там придется по ифельзить от души. :)

Поделюсь своими мыслями, как парсер можно написать в ОО-стиле.
Формат очень похож на примитивный скриптовый язык, в общем виде, строка представляет из себя команду с переменным числом аргументов:

cmd param1 param2 ... paramN

Мы можем ввести понятие команда - класс Command, от этого класса будут порождаться все команды.
Что это нам дает: команды легко добавляются, вся работ команды спрятана внутри ее класса.

Работа парсера в этому случае, будет сводиться к определению имени команды и передачи управления методу объекта класса-обработчика. В качестве параметра этому методу будет передаваться остаток строки, что бы он смог проверить и обработать все параметры.

P.S. И при парсинге любых тестовых форматов хорошо смогут помочь всякие flex+bison или boost::spirit.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 12, 2014, 07:21
Old, это какой-то паттерн?

Было бы здорово экспортирвать в XML. Пока ничего не нашёл.
По поводу экспортирования мне советовали это почитать: http://www.gamedev.ru/art/forum/?id=186016&page=2#m22 (http://www.gamedev.ru/art/forum/?id=186016&page=2#m22)
И это: http://ksolek.fm.interia.pl/Blender/ (http://ksolek.fm.interia.pl/Blender/)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 12, 2014, 07:28
Old, это какой-то паттерн?
Вы про что сейчас спрашивает? :)

И зачем вам xml? Что бы файл больше места занимал и дольше парсился? :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 12, 2014, 08:23
Я про Ваш Ответ #73. Я так понимаю, что это не имеет отношения к какому-либо паттерну, раз Вы переспросили.

С XML было бы легче работать. Но ведь есть же экспортёры в XML? Значит для чего-то люди их используют?


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 12, 2014, 08:28
Я про Ваш Ответ #73. Я так понимаю, что это не имеет отношения к какому-либо паттерну, раз Вы переспросили.
Вы про мысли о ОО-парсере? Это стандартный ОО-подход, когда вначале нужно выбрать сущности, которые участвуют в процессе.

С XML было бы легче работать. Но ведь есть же экспортёры в XML? Значит для чего-то люди их используют?
Можно то можно, хотя я не вижу, что это облегчит.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 12, 2014, 08:34
Может экспорт в XML служит для каких-то специфических целей? Хотя тот факт, что этот экспортёр надо отдельно устанавливать говорит о том, что используется он очень редко.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Hrundel от Апрель 12, 2014, 12:25
Из того, что сплит для Вас прост и удобен, ещё не следует, что он в этой задаче - оптимальное решение.. И, кстатии, ошибок в работе своего молотка я тоже пока не замечал, но это не значит, что его нужно использовать для решения проблем, которые под руку попадутся..)  

По ходу ваша обсессивная компульсивность меня начала раздражать. Думаю, что деструктивность - цель ваших сообщений. Я так понимаю, комплекс вашей неполноценности толкает вас к тому, чтобы самоутверждаться за чужой счет. Одобрение вам не известно, так как вас никто и никогда не одобраял, потому вы не умеете одобрять и поддерживать. Вы пытаетесь умышленно придераться к словам, или в просторечье - троллить. Вы жалки.

По-поводу процедурного стиля.. Наверное правильнее было сказать - процедурный подход решения проблемы..
Достаточно взглянуть на метод parseLine..
Я понимаю, конечно, что формат obj Вам упрощает задачу, и число этих if else if else по пальцам пересчитать, но что если чуть усложнить формат.. Вас бы не смутило, что этих if else if else стало бы стопятьсот? И всё это в одном методе..

Намекаете, что я о существовании switch не знаю? А вы еще и наглый.

Потом этот парсер выкинет вам исключение out of range, если чуть подпортить obj файл.. И пользователь вашего парсера не сможет его адекватно обработать.. Он даже не будет в курсе что произошло.. и как с этим дальше жить(
Но Вас, конечно, такие мелочи не беспокоят.. работает и ладно..

Вот, и именно, меня в данном коде такие мелочи не беспокоят. На универсальность он не претендует.

Итак, когда же мы увидем ваше бессмертное, не процедурное творение?
Да мы его и не увидем! Потому, что к вашей обсессивной компульсивности скорее всего еще примешивается параноидальная депрессия. Вы трус, который боится чужой критики и троль. Все ваши последующие сообщения в форуме будут мной проигнорированы. Я всегда призерал таких людей как вы.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: m_ax от Апрель 12, 2014, 13:06
Прелееестно) Посмеялся от души)  /* заскринел для истории */

Простите меня Hrundel, не предполагал, что Вы так ранимы(

 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 13, 2014, 13:01
По ходу ваша обсессивная компульсивность меня начала раздражать.
Да, неприятно когда некто "морщит носик" (с видом знатока), но ничего не предлагает взамен. Но все-таки надо сдержаться и свое раздражение оставить при себе.

А вообще критика "та еще". Вот напр
Да, здесь он "промахнулся", он должен был использовать QVector, т.к вы везде используете QVector. простите его, он просто этого не знал. :)
Откуда QVector - хз  ??? Я его не юзал и сказать такого не мог :) Ладно, залупнулся паренек, прихвастнул. Ну а по делу-то что? Как он собирался хранить массив индексов? И потом - "только треугольники" это упрощение позволительное студенту, но никак не профи. Полигон может ссылаться на любое число вертексов. Как хранить данные в этом случае?

Это все вещи на уровне "общей культуры программирования" - как организовать/поставить базовые данные. На пулеметы (нурбсы, триангуляция, материал и др) никто не посылал, мы же не звери. Но почему-то я уверен - даже для простых базовых задач никаких предложений не последует  :'( Хотя почему бы не проверить еще раз, мне это ничего не стоит


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 13, 2014, 14:36
Да, неприятно когда некто "морщит носик" (с видом знатока), но ничего не предлагает взамен.
Не переживайте, к этой вашей черте уже все привыкли. :)

А вообще критика "та еще". Вот напр
Фух, ну слава Богу, и я вам про это. :)

Я же и говорю, для чего было писать эту фигню:
Да еще контейнеры подобраны - полный ппц. Потому что голова занята не делом а "всякой всячиной"

Ладно, залупнулся паренек, прихвастнул. Ну а по делу-то что?
Да ничего он не хвастал. Он выбрал нормальный контейнер для этой задачи - QList.

Как он собирался хранить массив индексов?
Да он не собрался, он их спокойно хранит в этом QList. :)

И потом - "только треугольники" это упрощение позволительное студенту, но никак не профи.
У вас прямо глаза сегодня открылись. :)
Правильно, он и есть студент, он учится. Он еще понятия не имеет куда что и почем. :)

Полигон может ссылаться на любое число вертексов. Как хранить данные в этом случае?
А вот он столкнется и задумается. И запомнит на всю жизнь, как это делать лучше.

Это все вещи на уровне "общей культуры программирования" - как организовать/поставить базовые данные.
Конечно, и он эту культура начинает осваивать. Только сейчас начинает. А вы от него, что то требуете и называете халтурщиком. :)

На пулеметы (нурбсы, триангуляция, материал и др) никто не посылал, мы же не звери.
А никого никуда посылать и не надо. Как только ему это понадобиться, тогда он начнет этим интересоваться.

Но почему-то я уверен - даже для простых базовых задач никаких предложений не последует  :'(
О каких предложениях вы говорите?

Хотя почему бы не проверить еще раз, мне это ничего не стоит
Вам ничего не стоит проверить?

Последний абзац - вы как-то ушли в себя. :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 14, 2014, 12:36
Он выбрал нормальный контейнер для этой задачи - QList.
...
Да он не собрался, он их спокойно хранит в этом QList. :)
Что Вы скажете об инженере который вот просто так, без раздумий, увеличил расход памяти для базовых данных более чем в 3 раза? Может он добился этим др выгод? Наоборот, он не может даже подать их для рисования напрямую.

И куда же девается вся Ваша "грамотность", тонны прочитанных книг при первом самостоятельном решении? Это есть хотя бы у Александреску


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 14, 2014, 12:42
Что Вы скажете об инженере который вот просто так, без раздумий, увеличил расход памяти для базовых данных более чем в 3 раза?
То же что и вам, что он "профессионал". :)
А 8Observer8 ничего не скажу, потому что он не инженер, он только учиться. Этот контейнер вполне подходит для решения той задачи, которую он сейчас решает.

И куда же девается вся Ваша "грамотность", тонны прочитанных книг при первом самостоятельном решении?
У меня "грамотность" уменьшается постоянно, я стараюсь учиться и изучать все новое.
А вот ваша "грамотность" растет день ото дня, вместе с комплексами "большого специалиста". :)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: OKTA от Апрель 14, 2014, 12:56
А как пишут инженеры в циклах? ++i или i++?  ;D


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 19, 2014, 18:36
Улучшил немного свой парсер. Прототип:
Код
C++ (Qt)
   void parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes )
   throw(EmptyInput, BadLine);
 

Теперь он выбрасывает исключения:
- EmptyInput - если на входе пустая строка
Тогда пользователь увидит на экране:
"Input argument is empty."

- BadLine - если в строке некорректные данные. Причем пользователю выводится сама строка и номер строки в файле. К примеру, пользователь открыл файл .obj и случайно изменил какую-либо из строк:

Пользователь испортил строку с координатой x:
"v 1.000w000 1.000001 -0.999999"

Тогда пользователь увидит:
Error string "v 1.000w000 1.000001 -0.999999" at line 3

Либо случайно изменил строку с индексами:
f 1w 2 4

Тогда пользователь увидит:
Error string "f 1w 2 4" at line 12

Либо случайно удалил одну из координат:
"v -0.999999 -1.000001"

Тогда пользователь увидит:
Error string "v -0.999999 -1.000001" at line 4

Либо удалил один из индексов, то есть вместо:
"f 5 8 6"
Получилось так:
"f 8 6"

Тогда пользователь увидит:
Error string "f 8 6" at line 13

Задокументировал с помощью тестов срабатывание всех исключений выше:
Код
C++ (Qt)
#include <QString>
#include <QtTest>
#include "Parser.h"
#include <QVector3D>
#include "EmptyInput.h"
#include "BadLine.h"
 
enum ExceptionType {
   noException,
   emptyInput,
   badLine
};
 
class CubeFromBlenderTests : public QObject {
   Q_OBJECT
 
public:
   CubeFromBlenderTests( );
 
   static inline bool qFuzzyCompare( double p1, double p2, double delta ) {
       return ( qAbs( p1 - p2 ) <= delta * qMin( qAbs( p1 ), qAbs( p2 ) ));
   }
 
   private
Q_SLOTS:
   // Right result
   void testCase1_data( );
   void testCase1( );
 
   // Input string is empty
   void testCase2_data( );
   void testCase2( );
};
 
CubeFromBlenderTests::CubeFromBlenderTests( ) {
}
 
void CubeFromBlenderTests::testCase1_data( ) {
   QTest::addColumn<QString>("input");
   QTest::addColumn<QList<QVector3D> >("expected_points");
   QTest::addColumn<QList<QVector3D> >("expected_indexes");
   QTest::addColumn<bool>("isExpectedException");
 
   bool exception = true;
   bool no_exception = false;
 
   QString input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n"
           "# www.blender.org\n"
           "o Cube\n"
           "v 1.000000 1.000001 -0.999999\n"
           "v 1.000000 -0.999999 -1.000001\n"
           "v -1.000000 -0.999999 -1.000001\n"
           "v -1.000000 1.000001 -0.999999\n"
           "v 1.000000 0.999999 1.000001\n"
           "v 0.999999 -1.000001 0.999999\n"
           "v -1.000000 -1.000000 0.999999\n"
           "v -1.000000 0.999999 1.000001\n"
           "s off\n"
           "f 1 2 4\n"
           "f 5 8 6\n"
           "f 1 5 2\n"
           "f 2 6 3\n"
           "f 3 7 4\n"
           "f 5 1 8\n"
           "f 2 3 4\n"
           "f 8 7 6\n"
           "f 5 6 2\n"
           "f 6 7 3\n"
           "f 7 8 4\n"
           "f 1 4 8\n" );
   QList<QVector3D> expected_points;
   QVector3D point;
 
   // 1
   point.setX( 1.000000 );
   point.setY( 1.000001 );
   point.setZ( -0.999999 );
   expected_points.append( point );
 
   // 2
   point.setX( 1.000000 );
   point.setY( -0.999999 );
   point.setZ( -1.000001 );
   expected_points.append( point );
 
   // 3
   point.setX( -1.000000 );
   point.setY( -0.999999 );
   point.setZ( -1.000001 );
   expected_points.append( point );
 
   // 4
   point.setX( -1.000000 );
   point.setY( 1.000001 );
   point.setZ( -0.999999 );
   expected_points.append( point );
 
   // 5
   point.setX( 1.000000 );
   point.setY( 0.999999 );
   point.setZ( 1.000001 );
   expected_points.append( point );
 
   // 6
   point.setX( 0.999999 );
   point.setY( -1.000001 );
   point.setZ( 0.999999 );
   expected_points.append( point );
 
   // 7
   point.setX( -1.000000 );
   point.setY( -1.000000 );
   point.setZ( 0.999999 );
   expected_points.append( point );
 
   // 8
   point.setX( -1.000000 );
   point.setY( 0.999999 );
   point.setZ( 1.000001 );
   expected_points.append( point );
 
   QList<QVector3D> expected_indexes;
   QVector3D indexes;
 
   // 1
   indexes.setX( 1.0 );
   indexes.setY( 2.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 2
   indexes.setX( 5.0 );
   indexes.setY( 8.0 );
   indexes.setZ( 6.0 );
   expected_indexes.append( indexes );
 
   // 3
   indexes.setX( 1.0 );
   indexes.setY( 5.0 );
   indexes.setZ( 2.0 );
   expected_indexes.append( indexes );
 
   // 4
   indexes.setX( 2.0 );
   indexes.setY( 6.0 );
   indexes.setZ( 3.0 );
   expected_indexes.append( indexes );
 
   // 5
   indexes.setX( 3.0 );
   indexes.setY( 7.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 6
   indexes.setX( 5.0 );
   indexes.setY( 1.0 );
   indexes.setZ( 8.0 );
   expected_indexes.append( indexes );
 
   // 7
   indexes.setX( 2.0 );
   indexes.setY( 3.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 8
   indexes.setX( 8.0 );
   indexes.setY( 7.0 );
   indexes.setZ( 6.0 );
   expected_indexes.append( indexes );
 
   // 9
   indexes.setX( 5.0 );
   indexes.setY( 6.0 );
   indexes.setZ( 2.0 );
   expected_indexes.append( indexes );
 
   // 10
   indexes.setX( 6.0 );
   indexes.setY( 7.0 );
   indexes.setZ( 3.0 );
   expected_indexes.append( indexes );
 
   // 11
   indexes.setX( 7.0 );
   indexes.setY( 8.0 );
   indexes.setZ( 4.0 );
   expected_indexes.append( indexes );
 
   // 12
   indexes.setX( 1.0 );
   indexes.setY( 4.0 );
   indexes.setZ( 8.0 );
   expected_indexes.append( indexes );
 
   QTest::newRow( "parseData_01" ) << input << expected_points << expected_indexes << no_exception;
}
 
void CubeFromBlenderTests::testCase1( ) {
   QFETCH( QString, input );
   QFETCH( QList<QVector3D>, expected_points );
   QFETCH( QList<QVector3D>, expected_indexes );
   QFETCH( bool, isExpectedException );
 
   Parser parser;
   QList<QVector3D> points;
   QList<QVector3D> indexes;
 
   try {
       parser.parseData( input, points, indexes );
   } catch ( const LogicError& e ) {
       QVERIFY2( false, "Exception was occur." );
   } catch ( ... ) {
       QVERIFY2( false, "Uncaught exception." );
   }
 
   double delta = 0.0001;
   bool result = false;
   QString msg;
 
   // Check size of points and indexes
   QCOMPARE( points.size( ), expected_points.size( ) );
   QCOMPARE( indexes.size( ), expected_indexes.size( ) );
 
   // Check points
   for ( std::size_t i = 0; i < points.size( ); ++i ) {
       // Check x
       result = qFuzzyCompare( points[i].x( ), expected_points[i].x( ), delta );
       msg = QString( "\nActual: %1"
               "\nExpected: %2"
               "\nDelta: %3" ).arg( points[i].x( ) ).arg( expected_points[i].x( ) ).arg( delta );
       QVERIFY2( result, msg.toStdString( ).c_str( ) );
 
       // Check y
       result = qFuzzyCompare( points[i].y( ), expected_points[i].y( ), delta );
       msg = QString( "\nActual: %1"
               "\nExpected: %2"
               "\nDelta: %3" ).arg( points[i].y( ) ).arg( expected_points[i].y( ) ).arg( delta );
       QVERIFY2( result, msg.toStdString( ).c_str( ) );
 
       // Check z
       result = qFuzzyCompare( points[i].z( ), expected_points[i].z( ), delta );
       msg = QString( "\nActual: %1"
               "\nExpected: %2"
               "\nDelta: %3" ).arg( points[i].z( ) ).arg( expected_points[i].z( ) ).arg( delta );
       QVERIFY2( result, msg.toStdString( ).c_str( ) );
   }
 
   // Check indexes
   int actualIndex = 0;
   int expectedIndex = 0;
   for ( std::size_t i = 0; i < indexes.size( ); ++i ) {
       // 1
       actualIndex = (int) indexes[i].x( );
       expectedIndex = (int) indexes[i].x( );
       QCOMPARE( actualIndex, expectedIndex );
 
       // 2
       actualIndex = (int) indexes[i].y( );
       expectedIndex = (int) indexes[i].y( );
       QCOMPARE( actualIndex, expectedIndex );
 
       // 3
       actualIndex = (int) indexes[i].z( );
       expectedIndex = (int) indexes[i].z( );
       QCOMPARE( actualIndex, expectedIndex );
   }
}
 
void CubeFromBlenderTests::testCase2_data( ) {
   QTest::addColumn<QString>("input");
   QTest::addColumn<QList<QVector3D> >("expected_points");
   QTest::addColumn<QList<QVector3D> >("expected_indexes");
   QTest::addColumn<int>("exceptionType");
 
   QString input = QString( "" );
   QList<QVector3D> expected_points;
   QList<QVector3D> expected_indexes;
   ExceptionType exceptionType;
 
   exceptionType = emptyInput;
   QTest::newRow( "Empty input" ) << input << expected_points << expected_indexes << (int) exceptionType;
 
   input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n"
           "# www.blender.org\n"
           "o Cube\n"
           "v 1.000w000 1.000001 -0.999999\n"
           "v 1.000000 -0.999999 -1.000001\n"
           "v -1.000000 -0.999999 -1.000001\n"
           "v -1.000000 1.000001 -0.999999\n"
           "v 1.000000 0.999999 1.000001\n"
           "v 0.999999 -1.000001 0.999999\n"
           "v -1.000000 -1.000000 0.999999\n"
           "v -1.000000 0.999999 1.000001\n"
           "s off\n"
           "f 1 2 4\n"
           "f 5 8 6\n"
           "f 1 5 2\n"
           "f 2 6 3\n"
           "f 3 7 4\n"
           "f 5 1 8\n"
           "f 2 3 4\n"
           "f 8 7 6\n"
           "f 5 6 2\n"
           "f 6 7 3\n"
           "f 7 8 4\n"
           "f 1 4 8\n" );
   exceptionType = badLine;
   QTest::newRow( "Bad vertex" ) << input << expected_points << expected_indexes << (int) exceptionType;
 
   input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n"
               "# www.blender.org\n"
               "o Cube\n"
               "v 1.000000 1.000001 -0.999999\n"
               "v 1.000000 -0.999999 -1.000001\n"
               "v -1.000000 -0.999999 -1.000001\n"
               "v -1.000000 1.000001 -0.999999\n"
               "v 1.000000 0.999999 1.000001\n"
               "v 0.999999 -1.000001 0.999999\n"
               "v -1.000000 -1.000000 0.999999\n"
               "v -1.000000 0.999999 1.000001\n"
               "s off\n"
               "f 1w 2 4\n"
               "f 5 8 6\n"
               "f 1 5 2\n"
               "f 2 6 3\n"
               "f 3 7 4\n"
               "f 5 1 8\n"
               "f 2 3 4\n"
               "f 8 7 6\n"
               "f 5 6 2\n"
               "f 6 7 3\n"
               "f 7 8 4\n"
               "f 1 4 8\n" );
   exceptionType = badLine;
   QTest::newRow( "Bad index" ) << input << expected_points << expected_indexes << (int) exceptionType;
 
   input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n"
               "# www.blender.org\n"
               "o Cube\n"
               "v 1.000000 1.000001 -0.999999\n"
               "v -0.999999 -1.000001\n"
               "v -1.000000 -0.999999 -1.000001\n"
               "v -1.000000 1.000001 -0.999999\n"
               "v 1.000000 0.999999 1.000001\n"
               "v 0.999999 -1.000001 0.999999\n"
               "v -1.000000 -1.000000 0.999999\n"
               "v -1.000000 0.999999 1.000001\n"
               "s off\n"
               "f 1 2 4\n"
               "f 5 8 6\n"
               "f 1 5 2\n"
               "f 2 6 3\n"
               "f 3 7 4\n"
               "f 5 1 8\n"
               "f 2 3 4\n"
               "f 8 7 6\n"
               "f 5 6 2\n"
               "f 6 7 3\n"
               "f 7 8 4\n"
               "f 1 4 8\n" );
   exceptionType = badLine;
   QTest::newRow( "Deleted vertex" ) << input << expected_points << expected_indexes << (int) exceptionType;
 
   input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n"
               "# www.blender.org\n"
               "o Cube\n"
               "v 1.000000 1.000001 -0.999999\n"
               "v 1.000000 -0.999999 -1.000001\n"
               "v -1.000000 -0.999999 -1.000001\n"
               "v -1.000000 1.000001 -0.999999\n"
               "v 1.000000 0.999999 1.000001\n"
               "v 0.999999 -1.000001 0.999999\n"
               "v -1.000000 -1.000000 0.999999\n"
               "v -1.000000 0.999999 1.000001\n"
               "s off\n"
               "f 1 2 4\n"
               "f 8 6\n"
               "f 1 5 2\n"
               "f 2 6 3\n"
               "f 3 7 4\n"
               "f 5 1 8\n"
               "f 2 3 4\n"
               "f 8 7 6\n"
               "f 5 6 2\n"
               "f 6 7 3\n"
               "f 7 8 4\n"
               "f 1 4 8\n" );
   exceptionType = badLine;
   QTest::newRow( "Deleted index" ) << input << expected_points << expected_indexes << (int) exceptionType;
}
 
void CubeFromBlenderTests::testCase2( ) {
   QFETCH( QString, input );
   QFETCH( QList<QVector3D>, expected_points );
   QFETCH( QList<QVector3D>, expected_indexes );
   QFETCH( int, exceptionType );
 
   Parser parser;
   QList<QVector3D> points;
   QList<QVector3D> indexes;
 
   try {
       parser.parseData( input, points, indexes );
       if (exceptionType != noException) {
           QVERIFY2( false, "There is no exception." );
       } else {
           QVERIFY2( true, "" );
       }
   } catch ( const LogicError& e ) {
       switch( exceptionType ) {
       case noException:
           QVERIFY2( false, "Exception was occur." );
           break;
       case emptyInput:
           if ( std::string("Input argument is empty.") == std::string( e.what() ) ) {
               QVERIFY2( true, "" );
           } else {
               QVERIFY2( false, "We expecte EmptyInput exception." );
           }
           break;
       case badLine:
           if ( std::string("Error string \"v 1.000w000 1.000001 -0.999999\" at line 3") == std::string( e.what() ) ||
                std::string("Error string \"f 1w 2 4\" at line 12") == std::string( e.what() ) ||
                std::string("Error string \"v -0.999999 -1.000001\" at line 4") == std::string( e.what() ) ||
                std::string("Error string \"f 8 6\" at line 13") == std::string( e.what() ) ) {
               QVERIFY2( true, "" );
           } else {
               QVERIFY2( false, "We expecte BadLine exception." );
           }
           break;
       default:
           QVERIFY2( false, "We don't expecte this exception." );
           break;
       }
   } catch ( ... ) {
       QVERIFY2( false, "Uncaught exception." );
   }
}
 
QTEST_APPLESS_MAIN( CubeFromBlenderTests )
 
#include "tst_CubeFromBlenderTests.moc"
 

Так пользователь вызывает парсер:
Код
C++ (Qt)
   QList<QVector3D> points;
   QList<QVector3D> indexes;
   Parser parser;
 
   try {
       parser.parseData( all, points, indexes );
   } catch ( const LogicError &e ) {
       QMessageBox::information( this, tr( "Information" ), QString::fromUtf8( e.what() ) );
       return;
   } catch ( ... ) {
       QMessageBox::information( this, tr( "Information" ), tr( "Uncaught exception." ) );
       return;
   }
 

Вот классы исключений EmptyInput и BadLine:
EmptyInput.h
Код
C++ (Qt)
#ifndef EMPTYINPUT_H
#define EMPTYINPUT_H
 
#include "LogicError.h"
 
class EmptyInput : public LogicError {
public:
 
   EmptyInput( std::string argument ) : LogicError( argument ) {
       m_message = "Input argument is empty.";
   }
};
 
#endif // EMPTYINPUT_H
 

BadLine.h
Код
C++ (Qt)
#ifndef BADLINE_H
#define BADLINE_H
 
#include "LogicError.h"
#include <sstream>
 
class BadLine : public LogicError {
public:
 
   BadLine( const std::string &line, int lineNum ) :
       LogicError( line ), m_lineNum( lineNum ) {
       std::ostringstream ostr;
       ostr << "Error string \"" << line << "\" at line " << lineNum;
       m_message = ostr.str( );
   }
 
protected:
   int m_lineNum;
};
 
#endif // BADLINE_H
 

Вот сам парсер:
Parser.h
Код
C++ (Qt)
#ifndef PARSER_H
#define PARSER_H
 
#include <QList>
#include <QVector3D>
#include <QString>
#include "EmptyInput.h"
#include "BadLine.h"
 
class Parser {
public:
   void parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes )
   throw(EmptyInput, BadLine);
};
 
#endif // PARSER_H
 

Parser.cpp
Код
C++ (Qt)
#include "Parser.h"
#include <QStringList>
 
void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) throw(EmptyInput, BadLine) {
 
   if ( input.isEmpty( ) ) {
       throw( EmptyInput( input.toStdString( ) ) );
   }
 
   QStringList list = input.split( "\n" );
 
   for ( std::size_t i = 0; i < list.size( ); ++i ) {
       // Poitns
       if ( list[i][0] == QChar( 'v' ) ) {
           QStringList listForPoints = list[i].split( " " );
           if ( listForPoints.size( ) == 4 ) {
               bool ok;
               float x = listForPoints[1].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               float y = listForPoints[2].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               float z = listForPoints[3].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               points.append( QVector3D( x, y, z ) );
           } else {
               throw( BadLine( list[i].toStdString(), i ) );
           }
       }
 
       // Indexes
       if ( list[i][0] == QChar( 'f' ) ) {
           QStringList listForIndexes = list[i].split( " " );
           if ( listForIndexes.size( ) == 4 ) {
               bool ok;
               float x = listForIndexes[1].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               float y = listForIndexes[2].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               float z = listForIndexes[3].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               indexes.append( QVector3D( x, y, z ) );
           } else {
               throw( BadLine( list[i].toStdString(), i ) );
           }
       }
   }
}
 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 19, 2014, 19:03
Оказывается есть ограничение на количество символов в сообщении: 20000 символов :)

Не уместился класс LogicError:

LogicError.h
Код
C++ (Qt)
#ifndef LOGICERROR_H
#define LOGICERROR_H
 
#include <stdexcept>
 
class LogicError : public std::logic_error {
public:
 
   LogicError( std::string argument ) : std::logic_error( "" ), m_argument( argument ) {
 
   }
 
   virtual const char *what( ) const throw () {
       return m_message.c_str( );
   }
 
   virtual ~LogicError( ) throw () {
 
   }
 
protected:
   std::string m_argument;
   std::string m_message;
};
 
#endif // LOGICERROR_H
 


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Igors от Апрель 20, 2014, 09:18
Код
C++ (Qt)
               bool ok;
               float x = listForPoints[1].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               float y = listForPoints[2].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               float z = listForPoints[3].toFloat( &ok );
               if ( !ok ) {
                   throw( BadLine( list[i].toStdString(), i ) );
               }
 
               points.append( QVector3D( x, y, z ) );
           } else {
               throw( BadLine( list[i].toStdString(), i ) );
           }
 
Почему ничего не доходит? Зачем нужны исключения если все равно проверяться на каждом чтении? Напрашивалось напр так
Код
C++ (Qt)
const QStringList & v = listForPoints;
points.append( QVector3D( Read1V(v[1], Read1V(v[2]), Read1V(v[3]) ) );
 
А метод Read1V уже выбрасывает исключение. Для индексов аналогично.

Вместо того чтобы заниматься делом, содержательной частью - время тратится на "систему тестирования" (хз чего)


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 23, 2014, 08:45
Не понял ни слова :)

Почему ничего не доходит?
Что не доходит?

Зачем нужны исключения если все равно проверяться на каждом чтении?
Какая связь между чтением и исключениями?

Напрашивалось напр так
Код
C++ (Qt)
const QStringList & v = listForPoints;
points.append( QVector3D( Read1V(v[1], Read1V(v[2]), Read1V(v[3]) ) );
 
А метод Read1V уже выбрасывает исключение. Для индексов аналогично.
Здесь вообще ничего не понял.

Вместо того чтобы заниматься делом, содержательной частью - время тратится на "систему тестирования" (хз чего)
Я полностью реализовал содержательную часть. Задача была в загрузке объекта созданного в редакторе Blender.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 23, 2014, 09:11
Помогите, пожалуйста, понять и исправить. Хочу чтобы оси выходили за пределы куба, как на рисунке:

(http://i7.pixs.ru/storage/7/2/6/190png_3969499_11811726.png)

Исходники: https://github.com/8Observer8/Cube

А вот в том примере, который мне помог доделать Old, оси не покидают пределы куба:

(http://i6.pixs.ru/storage/6/5/0/189png_9281596_11811650.png)

Исходники: https://github.com/8Observer8/CubeFromBlender


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: Old от Апрель 23, 2014, 09:37
А вот в том примере, который мне помог доделать Old, оси не покидают пределы куба:
Так удлините оси. :)
В предыдущем примере вы руками задавали маленький куб, а куб блендера большой.


Название: Re: Создание массива вершин фигуры с помощью редактора
Отправлено: 8Observer8 от Апрель 23, 2014, 10:54
Точно! :) Спасибо огромное! :)

Кстати, я попробовал загрузить с помощью этой программы голову обезьяны из Blender'а:

(http://i6.pixs.ru/storage/5/5/3/191png_2818923_11812553.png)

Вот что получилось:

(http://i6.pixs.ru/storage/5/7/6/192png_4131707_11812576.png)

Голову обезьяны в Blender'е можно получить так:
- сначала удаляем куб по умолчанию, для этого нажимаем на клавиатуре: "Tab" -> "Del"
- в меню выбираем "Add" -> выбираем "Mesh" -> выбираем "Monkey"
- выделяем голову, для этого нажимаем клавишу "Tab"
- нажимаем Ctrl-t (это чтобы примитивы были треугольниками, а не квадратами)

А сохранить так:
- в меню выбираем "File" -> выбираем "Export" -> выбираем "Wavefront (.obj)"
- на панели слева убираем галочку: "Write Materials"
- ставим галочку: "Keep Vertex Order"
- нажимаем кнопку "Export OBJ"

Прикрепил obj-файл. Пока не понял, в чём проблема.