Автор Тема: си плюс плюс  (Прочитано 9148 раз)

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: си плюс плюс
« Ответ #15 : 30 Октябрь 2016, 22:02:15 »
Цитировать
Пытался:
 error: 'class povanim::BlenderObject' has no member named 'name'
Ну так и объяви name в объекте, а не в меше.

Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #16 : 30 Октябрь 2016, 22:27:26 »
>> и пишу его в map, как объект
... только добавлять нужно void addObject(std::string name,BlenderObject* ob) ...

BlenderMesh *mesh = new BlenderMesh();
mesh -> name = obname;
scene->addObject(name,mesh)

... если вызов addObject(name,mesh) не прокатит, пробуй addObject(name, (BlenderObject*) mesh) ...
... при этом name у тебя есть в объекте и name будет в списке? ...

... после того как получишь из списка BlenderObject* можешь сделать mesh=(BlenderMesh*) object ...


... сделай еще в BlenderObject наследуюмую функцию get_type которая возвращает код типа объекта ...
Значит, я правильно тебе предоставил данные, и правильно это использовал в своей проге (а, вот addObject(name, (BlenderObject*) mesh) не катит):
Код
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.28")
-- Checking for one of the modules 'python3'
-- Checking for one of the modules 'fox'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/leonid/workspace/programming/povanim_devel/build
Scanning dependencies of target povanim
[ 14%] Building CXX object CMakeFiles/povanim.dir/src/BlenderMesh.cpp.o
[ 28%] Building CXX object CMakeFiles/povanim.dir/src/RenderGUI.cpp.o
[ 42%] Building CXX object CMakeFiles/povanim.dir/src/main.cpp.o
[ 57%] Building CXX object CMakeFiles/povanim.dir/src/BlenderScene.cpp.o
[ 71%] Building CXX object CMakeFiles/povanim.dir/src/BlenderObject.cpp.o
[ 85%] Building CXX object CMakeFiles/povanim.dir/src/Vector.cpp.o
[100%] Linking CXX executable povanim
[100%] Built target povanim
Это значит, что я не знаю ничего про get_type, ибо тогда проблема в этой функции, где я пытался взять тип из меша:
Код
bool BlenderScene::addBlenderObject(std::string name){
    BlenderObject *bobject = objects.find(name) -> second;
    if (!bobject)
        return false;
    switch (bobject -> type) {
        case 2: {
            //Mesh *mesh = new Mesh();
            // reinterpret Blender mesh data to Povray mesh data
            // bla-bla-bla
        }
        case 1: { std::cout<<"Type: "<<"CSG"<<std::endl; break; } //del
        default: { std::cout<<"Type: "<<"BLOB"<<std::endl; } //del
    }
    return true;
}

Scanning dependencies of target povanim
[ 14%] Building CXX object CMakeFiles/povanim.dir/src/BlenderMesh.cpp.o
[ 28%] Building CXX object CMakeFiles/povanim.dir/src/RenderGUI.cpp.o
[ 42%] Building CXX object CMakeFiles/povanim.dir/src/main.cpp.o
[ 57%] Building CXX object CMakeFiles/povanim.dir/src/BlenderScene.cpp.o
/home/leonid/workspace/programming/povanim_devel/Povanim/src/BlenderScene.cpp: In member function 'bool BlenderScene::addBlenderObject(std::string)':
/home/leonid/workspace/programming/povanim_devel/Povanim/src/BlenderScene.cpp:194:24: error: 'class povanim::BlenderObject' has no member named 'type'
     switch (bobject -> type) {


Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #17 : 30 Октябрь 2016, 22:46:07 »
Не конпеляется. Пиши еще  :P . А если серьезно, то даже в твоем простом коде я уже ноги сломал. Объясни словами, что от чего хочешь наследовать или что там? Может и я пойму что.
Уже написал. Качай, конпеляй:
https://github.com/Lanuhum/Povanim

Цитировать
Класс "объект", его потомки: "меш", "кривая". Меши и кривые нужно вогнать в один массив, что ни так страшно, как потом их оттуда извлечь.
Вот из-за подобной хрени меня бесят языки со статической типизацией... В питоне такой проблемы нет, и можно даже иерархии классов не строить.
Да, я всё понимаю. Сам хотел все проблемы решить питоном. Но... нам может не нравиться форма ракеты...без гравицапы можно только по горизонтали, а с гравицапой в любую точку вселенной за 5 секунд...

mr.A

  • Гость
Re: си плюс плюс
« Ответ #18 : 30 Октябрь 2016, 23:33:50 »
Почему ты выбрал Fox, а не Qt например?

Оффлайн Samovar

  • Житель
Re: си плюс плюс
« Ответ #19 : 31 Октябрь 2016, 07:20:57 »
Почему ты выбрал Fox, а не Qt например?
говорит, что этот GUI  быстрее... но мне до сих пор непонятно, почему он начинает свои проги с обёртки, а не с начинки...

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: си плюс плюс
« Ответ #20 : 31 Октябрь 2016, 09:18:29 »
Цитировать
Допустим, у меня есть данные для меша, в данном случае имя. Что мне делать? Я делаю так:
BlenderMesh *mesh = new BlenderMesh();
mesh -> name = obname;
Так как меш наследник объекта, я и пишу его в map, как объект... понимаю, что, скорее всего, это неверно, и это первый повод материться.
Как мне превратить меш в объект?

Блин, мой вчерашний ответ
Цитировать
Например, так
Код: [Выделить]

BlenderObject *mesh = new BlenderMesh();
был формально правильным, но без разъяснений на 200 страницах абсолютно бесполезным, а времени долго отвечать особо не было, да и мозги хреново работали.

Попытаюсь ответить заново...

Яростные адепты ООП с топорами и в черных балахонах требуют, чтобы действия вроде
Код
mesh -> name = obname;
возможно было выполнять ТОЛЬКО из функций внутри объекта. Все так называемые данные-члены должны быть объявлены закрытыми (private). Функции класса BlenderMesh, конечно же, будут видеть свойство name, а всем остальным неположено.
Если мы создаём объект типа BlenderMesh, но присваиваем его указателю типа BlenderObject, то нам остаётся надеяться только на "магию виртуальных функций". Лучше про них отдельно прочитать в толстой книжке, но и я попробую кратко рассказать.
В классе BlenderObject мы объявляем виртуальную функцию:
Код
class BlenderObject{
...
virtual SuperFunction();
...
};

и классе BlenderMesh мы объявляем функцию с тем же именем:
Код
class BlenderMesh{
...
virtual SuperFunction();
...
};

ключевое слово virtual для наших целей обязательно.
Теперь, если мы у объекта (типа BlenderMesh), на который указывает указатель *mesh (а тип указателя BlenderObject), вызываем функцию SuperFunction,
Код
mesh -> SuperFunction();
то для объекта будет вызвана его личная функция. Если внутри этой функции есть строка
Код
this.name = obname;
она без проблем отработает.

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: си плюс плюс
« Ответ #21 : 31 Октябрь 2016, 09:34:02 »
Но все эти рассуждения правильны для какой-нибудь переменной класса BlenderMesh, которой нет в классе BlenderObject. Переменную name, в которой содержится имя объекта, лучше объявить в классе BlenderObject, всё равно она во всех его потомках понадобится. Тогда и присвоение этой переменной можно выполнять в функциях-членах BlenderObject, и не надо геморроиться с виртуальными функциями. Это я и имел ввиду, когда писал
Цитировать
Ну так и объяви name в объекте, а не в меше.

Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #22 : 31 Октябрь 2016, 17:46:01 »
Почему ты выбрал Fox, а не Qt например?
Потому что в ЭТО моё творение в конце концов будет включён полный код Поврея, пропатченный несколькими моими заплатками. Я действую с ведома разработчика Поврея и в согласии с лицензией Поврея. Я не силён в юридических аспектах программистской деятельности, но, по-моему, с Qt будут разногласия. Может, и с Лисом будут разногласия, но, я не достучался до них. Хотя, при успешной операции, возможно, Лиса заменит GTKMM-3.

говорит, что этот GUI  быстрее... но мне до сих пор непонятно, почему он начинает свои проги с обёртки, а не с начинки...
Тебе тоже советую начинать с обёртки, когда твоя программа будет зависеть от разного рода команд типа: "Открыть файл", "Подгрузить сцену ", "Запустить рендер" и так далее... :)
Кроме того, при запущенной гуёвине, я могу контролировать использование памяти и наблюдать ошибки, которых без гуёвины не пронаблюдать. Было так: жму кнопку рендер - памяти задействовано 900, ещё раз жму +450, ещё раз, ещё +450. Оказалось, что начинку пришлось полностью переписывать.
Переписал. Жму раз - 900, жму два - 900...жму десятый раз - 900, жму одиннадцатый раз - ошибка сегментирования. Каждый раз одиннадцатый случай - ошибка сегментирования. Как бы я это выявил без гуёвины? Именно, гуёвина помогла мне отыскать в начинке неверные решения. Теперь ошибок сегментирования нет.
Вывод напрашивается сам : гуёвина помогает мне изучать язык программирования С++
Но, собственно, это уже ни начало, а конец, почти. Осталось написать вот эту фунцию, про которую мы вчера тут беседовали. Далее, нужно писать патчи и впиливать Поврей. Когда всё получится, можно будет считать, что я достаточно изучил С++, чтобы продолжить работу над рендером на GPU.
:)

Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #23 : 31 Октябрь 2016, 18:09:59 »
...
Ничего мне не понятно. Ладно, name, но у меша есть массив полигонов, его как мне передать объекту? Вроде как передаю компилируется, меш становится объектом, а вытащить из него ничего не получается. Что ни запросишь, ничего нет из того, что должно быть. Такое ощущение, что меш превращается в пустой объект.
Я ж и говорю, что какая-то непонятная эта штука "наследование". Когда в букваре про лошадок, наездников и боевых единицах, то это одно, а когда наследуются массивы в массивах, то про это, наверное на шестом курсе университета рассказывают.
Я попробую без наследников. Попробую шаблон Data<T> использовать в классе "Объект" и создавать и вызывать объект:
BlenderObject *bobject = new BlenderObject();
Безо всяких там рокировок и подстановок BlenderMesh.

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: си плюс плюс
« Ответ #24 : 31 Октябрь 2016, 18:28:39 »
Цитировать
Я попробую без наследников.
Тогда в массиве можно будет содержать только объекты типа BlenderObject. Разнородные объекты в один класс можно загнать, но это будет неудобно. Впрочем, в построении иерархий классов тоже мало удобства...

Цитировать
Ладно, name, но у меша есть массив полигонов, его как мне передать объекту?
А откуда тебе его надо передавать? Обычно это делают как-то так:
Код
class BlenderMesh{
private:
float* array;
int nsize
...
public:
...
void SetArray(float* array, int nsize);
...
};

void BlenderMesh::SetArray(float* array, int nsize){
this.nsize=nsize;
this.array=array;
};
И в  нужном месте вызывают функцию SetArray.

Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #25 : 31 Октябрь 2016, 18:50:03 »
Тогда в массиве можно будет содержать только объекты типа BlenderObject. Разнородные объекты в один класс можно загнать, но это будет неудобно. Впрочем, в построении иерархий классов тоже мало удобства...
Я представляю как-то так:
Код
class object{
    public:
        int  Type;
        string       Name;
        Data<T>  Data;
                        Object();
                        ~Object();
        void         setData(Data<T>  Data);
};

Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #26 : 31 Октябрь 2016, 18:58:30 »
Вот, кажется нашёл в одном из накачанных примеров рейтрейсеров про наследников и то, как это делается

Object.h

Код
#ifndef __OBJECT_H
#define __OBJECT_H

#include <vector>
#include "IntersectData.h"
#include "Vector.h"
#include "Material.h"
#include "Ray.h"

enum IntersectType {
    HIT, MISS
};

class Object {
public:
    Point3                  position;
    Material *              material;
//    ObjectTransformer       transformer;

    // object hierarchy can have multiple children but just one parent
    // each child has coordinates relative to the parent's object space axes.
    std::vector<Object*>    children;
    Object *                parent;

                            Object();
    virtual                 ~Object();
    virtual Vector3         getNormalAt(const Point3 &p) const = 0;
    virtual IntersectType   intersect(const Ray &ray, IntersectData *data) const = 0;
    virtual void            computeBoundingBox() = 0;

    virtual void            rotate(const Vector3 &axis, float radians);
};

#endif

Mesh.h

Код
#ifndef __MESH_H
#define __MESH_H

#include "IntersectData.h"
#include "Triangle.h"
#include "Ray.h"
#include "Vector.h"
#include <vector>

class Mesh : public Object {
public:
    std::vector<Vector3*>   vertices;
    std::vector<Vector3*>   normals;

                            Mesh();
                            Mesh(const Point3 &pos);
                            ~Mesh();

    Point3                  bboxMin;
    Point3                  bboxMax;

    void                    addVertex(float x, float y, float z);
    void                    addNormal(float x, float y, float z);

    virtual IntersectType   intersect(const Ray &ray, IntersectData *data) const;
    virtual Vector3         getNormalAt(const Point3 &p) const;
    virtual void            computeBoundingBox();
    virtual void            rotate(const Vector3 &axis, float radians);
};
#endif

scene.cpp

Код
void Scene::teapot() {
    Color white = Color(1,1,1);
    Color purple = Color(0.75, 0, 0.75);

    Plane *plane = new Plane(Point3(0, -2, 0), Vector3(0, 1, 0));
    plane->material->color = purple;

    Mesh *mesh = new Mesh(Point3(0,0,0));
    mesh->material->color = white;
    Util::loadObj("meshes/teapot.obj", mesh);
    calculateBbox(mesh);

    //mesh->rotate(Vector3(1,0,0), 3.141592/4.0f);
    //rotateX(*mesh, 3.141592/4.0f);

    objects.push_back(dynamic_cast<Object*>(mesh));
    objects.push_back(dynamic_cast<Object*>(plane));
   
    m = mesh;
}
Часто нахожу ответы здесь:
http://alenacpp.blogspot.ru/2005/08/c.html
Цитата оттуда:
Цитировать
Приведение типов в C плюс плюс

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

Третий:
dynamic_cast
Безопасное приведение по иерархии наследования, в том числе и для виртуального наследования.
dynamic_cast<derv_class *>(base_class_ptr_expr)
Используется RTTI (Runtime Type Information), чтобы привести один указатель на объект класса к другому указателю на объект класса.
Классы должны быть полиморфными, то есть в базовом классе должна быть хотя бы одна виртуальная функция.
Если эти условие не соблюдено, ошибка возникнет на этапе компиляции.
Если приведение невозможно, то об этом станет ясно только на этапе выполнения программы и будет возвращен NULL.
dynamic_cast<derv_class &>(base_class_ref_expr)
Работа со ссылками происходит почти как с указателями, но в случае ошибки во время исполнения будет выброшено исключение bad_cast.

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: си плюс плюс
« Ответ #27 : 31 Октябрь 2016, 19:26:19 »
Тогда в массиве можно будет содержать только объекты типа BlenderObject. Разнородные объекты в один класс можно загнать, но это будет неудобно. Впрочем, в построении иерархий классов тоже мало удобства...
Я представляю как-то так:
Код
class object{
    public:
        int  Type;
        string       Name;
        Data<T>  Data;
                        Object();
                        ~Object();
        void         setData(Data<T>  Data);
};

А что такое у тебя будет <T>  ? Классы с разными типами вместо  <T> будут существенно разными типами, и в один массив их нельзя будет пихать. Так что если хочешь попытаться не использовать наследование и виртуальные функции (и нафига тогда С++, можно просто С), то тебе в данные-члены нужно загнать ВСЁ, что могло бы понадобиться в потомках этого Object, а потом использовать или игнорировать часть из них.

Оффлайн LanuHum

  • Житель
Re: си плюс плюс
« Ответ #28 : 31 Октябрь 2016, 19:48:52 »
Тогда в массиве можно будет содержать только объекты типа BlenderObject. Разнородные объекты в один класс можно загнать, но это будет неудобно. Впрочем, в построении иерархий классов тоже мало удобства...
Я представляю как-то так:
Код
class object{
    public:
        int  Type;
        string       Name;
        Data<T>  Data;
                        Object();
                        ~Object();
        void         setData(Data<T>  Data);
};

А что такое у тебя будет <T>  ? Классы с разными типами вместо  <T> будут существенно разными типами, и в один массив их нельзя будет пихать. Так что если хочешь попытаться не использовать наследование и виртуальные функции (и нафига тогда С++, можно просто С), то тебе в данные-члены нужно загнать ВСЁ, что могло бы понадобиться в потомках этого Object, а потом использовать или игнорировать часть из них.
Ну, во-первых, я хотел было попытаться уйти от виртуальных функций в рамках С++, пытаясь найти равноценное решение, но раз ты утверждаешь, что с шаблоном я заблуждаюсь, то буду курить dinamic_cast. Просто я читал, что шаблоны применяются там, где заранее неизвестно, какого типа будет содержимое, и подумал неверно. Спасибо, что растолковал! :)
Во-вторых, С++ я выбрал, так как очень хотел портировать джавовский код рейтрейсера, а там почти С++. Тулкиты на плюсах, поврей на плюсах, яфа на плюсах. Было желание когда-то (...или от безысходности бытия...) позаимствовать то оттуда, то отсюда нужное и лучшее. На си без плюсов я только блендер интернал рендер видел... :)

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: си плюс плюс
« Ответ #29 : 31 Октябрь 2016, 19:52:56 »
Цитировать
Вот, кажется нашёл в одном из накачанных примеров рейтрейсеров про наследников и то, как это делается
...

Код
    objects.push_back(dynamic_cast<Object*>(mesh));
    objects.push_back(dynamic_cast<Object*>(plane));
Я тебе примерно это и толковал...

Но тут мои собственные знания и заканчиваются, к сожалению. Мне непонятно, как этот рейтрейсер, работая с массивом objects понимает, где тут Mesh, где Plane, и т.д., и, самое главное, как к ним применять функции, специфичные для этих разных классов? Я представляю себе такую возможность только через собственные виртуальные функции (здесь это intersect, computeBoundingBox, getNormalAt и rotate), а вот где-то извне... Ну разве что бесконечно длинные простыни со switch-case (терпеть их не могу).
Поищи там пример такого разбора.

 


Яметрика

* По форуму

* Рекламный блок

* Последние вложения

1 (1).png
Скачано: 68
Автор: LEXA ANЭGROWND
blender.png
Скачано: 78
Автор: ipv2007
4.png
Скачано: 100
Автор: hiroyukiss
2.png
Скачано: 122
Автор: hiroyukiss

Скачано: 112
Автор: Dilifa12