~ubuntu-branches/ubuntu/edgy/k3d/edgy-proposed

« back to all changes in this revision

Viewing changes to modules/mesh/subdiv_algorithms.cpp

  • Committer: Bazaar Package Importer
  • Author(s): David Martínez Moreno
  • Date: 2005-04-28 18:38:10 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050428183810-kvc6nz46z6gheo0k
Tags: 0.4.5.0-5
* AAAAAAAARGH, *patching* configure.ac broke again the build process! Fixed
  (I hope).
* Removed more cruft of shaderpreprocessor/ from configure.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include "subdiv_algorithms.h"
25
25
 
 
26
#include <k3dsdk/basic_math.h>
26
27
#include <k3dsdk/result.h>
27
28
#include <k3dsdk/irenderman.h>
28
29
 
 
30
#include <boost/multi_array.hpp>
 
31
 
29
32
#include <cmath>
30
33
#include <map>
31
34
#include <set>
350
353
        const bool m_ignore_selection;
351
354
};
352
355
 
353
 
void catmull_clark(const unsigned long Levels, const k3d::mesh& Input, k3d::mesh& Output, const bool ignore_selection)
 
356
void catmull_clark(const unsigned long Levels, const k3d::mesh& Input, k3d::mesh& Output, const bool ignore_selection, const bool ignore_mesh_type)
354
357
{
355
358
        // clear the output
356
359
        Output.polyhedra.clear();
357
360
        k3d::deep_copy(Input, Output);
358
361
        for(k3d::mesh::polyhedra_t::iterator it = Output.polyhedra.begin(); it != Output.polyhedra.end(); ++it) {
359
 
                if((*it)->type == k3d::polyhedron::CATMULL_CLARK_SUBDIVISION_MESH || !ignore_selection) {
 
362
                if((*it)->type == k3d::polyhedron::CATMULL_CLARK_SUBDIVISION_MESH || !ignore_selection || ignore_mesh_type) {
360
363
                        k3d::polyhedron* output_polyhedron = *(it);
361
364
                        for(unsigned long i = 1; i <= Levels; i++) {
362
365
                                assert(output_polyhedron);
476
479
                }
477
480
        }
478
481
}
 
482
 
 
483
/// class link
 
484
class link
 
485
{
 
486
public:
 
487
        link(k3d::split_edge* Edge, bool dummy_edge = false) : edge(Edge), counter_clockwise(0), companion_clockwise(0), companion(0), m_Complete(false), m_Dummy_edge(dummy_edge)
 
488
        {
 
489
        }
 
490
        
 
491
        ~link()
 
492
        {
 
493
                if (!is_complete() && m_Dummy_edge && edge)
 
494
                {
 
495
                        delete edge;
 
496
                }
 
497
        }
 
498
 
 
499
        /// the split_edge associated with this link
 
500
        k3d::split_edge* edge;
 
501
        /// counter-clockwise link to this one
 
502
        link* counter_clockwise;
 
503
        /// clockwise link to the companion of this one
 
504
        link* companion_clockwise;
 
505
        /// link with the companion edge
 
506
        link* companion;
 
507
        /// true if the link is completed
 
508
        bool is_complete()
 
509
        {
 
510
                return m_Complete;
 
511
        }
 
512
        /// complete the link, i.e. set the actual companion and face_clockwise on the k3d::split_edge that is represented by the link
 
513
        void complete(bool recurse = true)
 
514
        {
 
515
                if (is_complete())
 
516
                {
 
517
                        return;
 
518
                }
 
519
                m_Complete = true;
 
520
                return_if_fail(edge);
 
521
                return_if_fail(edge->vertex);
 
522
                return_if_fail(counter_clockwise);
 
523
                return_if_fail(companion_clockwise);
 
524
                return_if_fail(companion);
 
525
                if (recurse)
 
526
                {
 
527
                        companion->complete(false);
 
528
                }
 
529
                return_if_fail(companion->edge);
 
530
                return_if_fail(companion_clockwise->edge);
 
531
                companion->edge->face_clockwise = companion_clockwise->edge;
 
532
                return_if_fail(counter_clockwise->edge);
 
533
                counter_clockwise->edge->face_clockwise = edge;
 
534
                if (!(edge->companion))
 
535
                        k3d::join_edges(*edge, *(companion->edge));
 
536
        }
 
537
private:
 
538
        bool m_Complete;
 
539
        bool m_Dummy_edge;
 
540
};
 
541
 
 
542
class point
 
543
{
 
544
        friend void splitter::make_creases();
 
545
public:
 
546
        point() : vertex(0), m_Reorder(false) {}
 
547
        point(k3d::point* Point) : vertex(Point), m_Reorder(false), m_Updated(false) {}
 
548
        virtual ~point()
 
549
        {
 
550
                for (unsigned long i = 0; i < links.size(); ++i)
 
551
                {
 
552
                        delete links[i];
 
553
                }
 
554
        }
 
555
        /// the point represented
 
556
        k3d::point* vertex;
 
557
        /// update the relations between the links. Works correctly only if links are ordered clockwise around the vertex. Use reorder_on if this is not the case.
 
558
        virtual void update()
 
559
        {
 
560
                m_Updated = true;
 
561
                if (m_Reorder)
 
562
                        reorder();
 
563
                for (unsigned long i = 0; i < links.size(); ++i)
 
564
                {
 
565
                        links[i]->counter_clockwise = links[(i+1) % links.size()]->companion;
 
566
                        links[i]->companion_clockwise = links[(links.size()+i-1) % links.size()];
 
567
                }
 
568
        }
 
569
        virtual link* join(point* other_point, bool recurse = true)
 
570
        {
 
571
                link* new_link = new link(new k3d::split_edge(vertex));
 
572
                links.push_back(new_link);
 
573
                if (recurse)
 
574
                {
 
575
                        new_link->companion = other_point->join(this, false);
 
576
                        new_link->companion->companion = new_link;
 
577
                }
 
578
                return new_link;
 
579
        }
 
580
                
 
581
        /// complete all links
 
582
        virtual void complete()
 
583
        {
 
584
                return_if_fail(m_Updated);
 
585
                for (unsigned long i = 0; i < links.size(); ++i)
 
586
                {
 
587
                        links[i]->complete();
 
588
                }
 
589
        }
 
590
        
 
591
        /// Turn on automatic link reordering, arranging links clockwise around the face normal.
 
592
        void reorder_on(k3d::vector3& normal)
 
593
        {
 
594
                m_Reorder = true;
 
595
                m_Normal = normal / normal.Length();
 
596
        }
 
597
        
 
598
private:
 
599
        /// reorder the links around the vertex so they are arranged clockwise around the normal vector of the face.
 
600
        void reorder()
 
601
        {
 
602
                if (links.size() < 1)
 
603
                        return;
 
604
                std::map<double, link*> angle_links;
 
605
                
 
606
                k3d::vector3 v0 = links[0]->companion->edge->vertex->position - vertex->position;
 
607
                
 
608
                for (unsigned long i = 0; i < links.size(); ++i)
 
609
                {
 
610
                        k3d::vector3 v = links[i]->companion->edge->vertex->position - vertex->position;
 
611
                        angle_links[angle(v0, v)] = links[i];
 
612
                }
 
613
                
 
614
                unsigned long i = 0;
 
615
                for (std::map<double, link*>::iterator it = angle_links.begin(); it != angle_links.end(); ++it)
 
616
                {
 
617
                        links[i] = it->second;
 
618
                        ++i;
 
619
                }
 
620
        }
 
621
        /// Calculate the angle between 2 vectors
 
622
        double angle(k3d::vector3& v1, k3d::vector3& v2)
 
623
        {
 
624
                // cosine of the angle:
 
625
                double cos_th = (v1 * v2) / (v1.Length() * v2.Length());
 
626
                //sometimes this value is greater than 1
 
627
                if (cos_th > 1.0)
 
628
                        cos_th = 1.0;
 
629
                if (cos_th < -1.0)
 
630
                        cos_th = -1.0;
 
631
                k3d::vector3 normal = (v1 ^ v2);
 
632
                normal /= normal.Length();
 
633
                double tol = 0.00001;
 
634
                // the angle
 
635
                double th = (normal + m_Normal).Length() > tol ? acos(cos_th) : k3d::pi_times_2() - acos(cos_th);
 
636
                //std::cerr << debug << "cos_th: " << cos_th << ". angle is " << th * 180 / k3d::pi() << " degrees" << std::endl;
 
637
                return th;
 
638
        }
 
639
        k3d::vector3 m_Normal;
 
640
        bool m_Reorder;
 
641
        bool m_Updated;
 
642
protected:
 
643
        /// a vector of all links from this point
 
644
        std::vector<link*> links;
 
645
};
 
646
 
 
647
// point at a t-junction. links[0] is the incomplete link (the leg of the T)
 
648
class t_point : public point
 
649
{
 
650
public:
 
651
        t_point(k3d::point* Point, k3d::split_edge* To, k3d::split_edge* From, bool dummy_edge = false)
 
652
        {
 
653
                this->vertex = Point;
 
654
                link* leg = new link(new k3d::split_edge(vertex), dummy_edge);
 
655
                leg->counter_clockwise = new link(To);
 
656
                leg->companion_clockwise = new link(From);
 
657
                links.push_back(leg);
 
658
                m_linked = false;
 
659
        }
 
660
        
 
661
        ~t_point()
 
662
        {
 
663
                delete links[0]->counter_clockwise;
 
664
                delete links[0]->companion_clockwise;
 
665
        }
 
666
        
 
667
        void update()
 
668
        {
 
669
                return_if_fail(links.size() == 1);
 
670
                if (!m_linked)
 
671
                        return;
 
672
                link* leg = links[0];
 
673
                return_if_fail(leg->edge);
 
674
                return_if_fail(leg->counter_clockwise);
 
675
                return_if_fail(leg->companion);
 
676
                return_if_fail(leg->companion_clockwise);
 
677
        }
 
678
        link* join(point* other_point, bool recurse = true)
 
679
        {
 
680
                m_linked = true;
 
681
                link* leg = links[0];
 
682
                if (recurse)
 
683
                {
 
684
                        leg->companion = other_point->join(this, false);
 
685
                        leg->companion->companion = leg;
 
686
                }
 
687
                return leg;
 
688
        }
 
689
        void complete()
 
690
        {
 
691
                if (!m_linked)
 
692
                        return;
 
693
                links[0]->complete();
 
694
        }
 
695
private:
 
696
        bool m_linked;
 
697
};
 
698
 
479
699
/// class splitter
480
 
k3d::split_edge* splitter::split_edge(k3d::split_edge& Edge, const double factor)
481
 
{
482
 
        double sharpness = get_sharpness(Edge);
483
 
        double comp_sharpness = Edge.companion ? get_sharpness(*(Edge.companion)) : 0.0;
484
 
 
 
700
splitter::splitter(k3d::polyhedron& Polyhedron, k3d::mesh::points_t& Points, bool Use_selection) : m_Polyhedron(Polyhedron), m_Points(Points)
 
701
{
 
702
        for (unsigned long i = 0; i < Polyhedron.faces.size(); ++i)
 
703
        {
 
704
                m_all_faces[Polyhedron.faces[i]->first_edge] = Polyhedron.faces[i];
 
705
                k3d::split_edge* last_edge = Polyhedron.faces[i]->first_edge;
 
706
                k3d::split_edge* this_edge = last_edge->face_clockwise;
 
707
 
 
708
                bool has_selected_edge = false;
 
709
                has_selected_edge = get_sharpness(*last_edge) > 0.0 ? true : has_selected_edge;
 
710
                
 
711
                if (Use_selection && last_edge->vertex->selected)
 
712
                        has_selected_edge = true;
 
713
 
 
714
                k3d::point* centroid = new k3d::point(last_edge->vertex->position);
 
715
 
 
716
                unsigned long corners = 1;
 
717
 
 
718
                while(this_edge != Polyhedron.faces[i]->first_edge)
 
719
                {
 
720
                        ++corners;
 
721
                        centroid->position += this_edge->vertex->position;
 
722
                        has_selected_edge = get_sharpness(*this_edge) > 0.0 ? true : has_selected_edge;
 
723
                        if (Use_selection && this_edge->vertex->selected)
 
724
                                has_selected_edge = true;
 
725
                        last_edge = this_edge;
 
726
                        this_edge = this_edge->face_clockwise;
 
727
                }
 
728
                if (has_selected_edge)
 
729
                {
 
730
                        point_edge_info info;
 
731
                        info.second[1] = last_edge;
 
732
                        centroid->position /= corners;
 
733
                        last_edge = Polyhedron.faces[i]->first_edge;
 
734
                        this_edge = last_edge->face_clockwise;
 
735
                        info.second[0] = this_edge;
 
736
                        info.second[2] = last_edge->companion;
 
737
                        info.first[1] = add_point(centroid);
 
738
                        m_edges[last_edge] = info;
 
739
 
 
740
                        while(this_edge != Polyhedron.faces[i]->first_edge)
 
741
                        {
 
742
                                info.second[0] = this_edge->face_clockwise;
 
743
                                info.second[1] = last_edge;
 
744
                                info.second[2] = this_edge->companion;
 
745
                                info.first[0] = add_t_point(this_edge->vertex, last_edge, this_edge, true);
 
746
                                info.first[1] = add_point(centroid);
 
747
                                m_edges[this_edge] = info;
 
748
                                last_edge = this_edge;
 
749
                                this_edge = this_edge->face_clockwise;
 
750
                        }
 
751
                        m_edges[Polyhedron.faces[i]->first_edge].first[0] = add_t_point(Polyhedron.faces[i]->first_edge->vertex, last_edge, Polyhedron.faces[i]->first_edge, true);
 
752
                        m_faces[Polyhedron.faces[i]->first_edge] = Polyhedron.faces[i];
 
753
                        m_centroids.push_back(centroid);
 
754
                }
 
755
                else
 
756
                {
 
757
                        delete centroid;
 
758
                }
 
759
        }
 
760
}
 
761
 
 
762
splitter::~splitter()
 
763
{
 
764
        for (unsigned long i = 0; i < m_centroids.size(); ++i)
 
765
        {
 
766
                delete m_centroids[i];
 
767
        }
 
768
        
 
769
        for (unsigned long i = 0; i < m_added_points.size(); ++i)
 
770
        {
 
771
                delete m_added_points[i];
 
772
        }
 
773
}
 
774
 
 
775
point* splitter::split_edge(k3d::split_edge& Edge, const double Factor, point* Start, point* End)
 
776
{
485
777
        // first point of the edge:
486
 
        k3d::point* this_point = Edge.vertex;
 
778
        k3d::point* this_point = (!Start || (Start->vertex == 0)) ? Edge.vertex : Start->vertex;
487
779
        // second point of the edge:
488
 
        k3d::point* other_point = Edge.face_clockwise->vertex;
489
 
        std::cerr << debug << "Starting split_edge with [" << this_point->position[0] << ", " << this_point->position[1] << ", " << this_point->position[2] << "] and [" << other_point->position[0] << ", " << other_point->position[1] << ", " << other_point->position[2] << "]" << std::endl;
490
 
        double f = factor;
 
780
        k3d::point* other_point = (!End || (End->vertex == 0)) ? Edge.face_clockwise->vertex : End->vertex;
491
781
        // new point position:
492
782
        k3d::vector3 new_pos;
493
 
        k3d::split_edge* ret_edge = 0;
494
 
        point_map::iterator it = m_other_points.find(this_point);
495
 
        if(it != m_other_points.end()) {
496
 
                this_point = (other_point == it->second.first) ? it->second.second : it->second.first;
497
 
                ret_edge = &Edge;
498
 
        } else {
499
 
                it = m_other_points.find(other_point);
500
 
                if(it != m_other_points.end()) {
501
 
                        other_point = (this_point == it->second.first) ? it->second.second : it->second.first;
502
 
                        ret_edge = Edge.face_clockwise;
503
 
                }
504
 
        }
505
 
        std::cerr << debug << "Finishing split_edge with [" << this_point->position[0] << ", " << this_point->position[1] << ", " << this_point->position[2] << "] and [" << other_point->position[0] << ", " << other_point->position[1] << ", " << other_point->position[2] << "]" << std::endl;
506
 
        new_pos = k3d::mix<k3d::vector3>(this_point->position, other_point->position, f);
507
 
        if(Edge.companion && m_split_edges.find(Edge.companion) != m_split_edges.end()) {
508
 
                std::cerr << debug << "Mixing old and new split-point." << std::endl;
509
 
                it->first->position = k3d::mix<k3d::vector3>(new_pos, it->first->position, 0.5);
510
 
                return ret_edge;
511
 
        }
512
 
        std::cerr << debug << "Split edge [" << Edge.vertex->position[0] << ", " << Edge.vertex->position[1] << ", " << Edge.vertex->position[2] << "]->[" << other_point->position[0] << ", " << other_point->position[1] << ", " << other_point->position[2] << "] at [" << new_pos[0] << ", " << new_pos[1] << ", " << new_pos[2] << "]" << std::endl;
 
783
        new_pos = k3d::mix<k3d::vector3>(this_point->position, other_point->position, Factor);
513
784
        // new point:
514
 
        std::cerr << debug << "Adding new point [" << new_pos[0] << ", " << new_pos[1] << ", " << new_pos[2] << "]" << std::endl;
515
785
        k3d::point* new_point = new k3d::point(new_pos);
516
 
        m_Points.push_back(new_point);
517
786
        // new edge:
518
787
        k3d::split_edge* new_edge = new k3d::split_edge(new_point, Edge.face_clockwise);
519
788
        Edge.face_clockwise = new_edge;
520
 
        new_edge->tags["crease"] = sharpness;
521
789
        // companion edge
522
790
        if(Edge.companion) {
523
791
                k3d::split_edge* new_comp_edge = new k3d::split_edge(new_point, Edge.companion->face_clockwise);
525
793
                k3d::join_edges(*Edge.companion, *new_edge);
526
794
                k3d::join_edges(Edge, *new_comp_edge);
527
795
                m_Polyhedron.edges.push_back(new_comp_edge);
528
 
                new_comp_edge->tags["crease"] = comp_sharpness;
529
 
        }
530
 
        m_Polyhedron.edges.push_back(new_edge);
531
 
        m_other_points[new_edge->vertex] = std::pair<k3d::point*, k3d::point*>(this_point, other_point);
532
 
        //m_split_edges.insert(Edge.companion);
533
 
        return new_edge;
534
 
}
535
 
 
536
 
k3d::split_edge* splitter::detach_edge_novertex(k3d::split_edge& Edge, const k3d::vector3& centroid)
537
 
{
538
 
        std::cerr << debug << "detach_edge_novertex" << std::endl;
539
 
        k3d::split_edge* clockwise = Edge.face_clockwise;
540
 
        //double f = adapt_factor(*clockwise, m_f);
541
 
        double f = 2*sqrt(m_f * m_parallel_edges[clockwise]);
542
 
        f = f > 1.0 ? 1.0 : f;
543
 
        std::cerr << debug << "Moving [" << clockwise->vertex->position[0] << ", " << clockwise->vertex->position[1] << ", " << clockwise->vertex->position[2] << "] to [";
544
 
        //clockwise->vertex->position = k3d::mix(clockwise->vertex->position, clockwise->face_clockwise->vertex->position, f);
545
 
        clockwise->vertex->position = k3d::mix(Edge.vertex->position, centroid, f);
546
 
        m_other_points.erase(clockwise->vertex);
547
 
        std::cerr << debug << clockwise->vertex->position[0] << ", " << clockwise->vertex->position[1] << ", " << clockwise->vertex->position[2] << "]" << std::endl;
548
 
        m_last_factor[clockwise] = f;
549
 
        clockwise->companion->face_clockwise->vertex = Edge.vertex;
550
 
        m_last_factor.erase(clockwise->companion->face_clockwise);
551
 
        m_split_edges.erase(clockwise->companion->face_clockwise);
552
 
        if(clockwise->companion->face_clockwise->companion) {
553
 
                clockwise->companion->face_clockwise->companion->face_clockwise = clockwise->companion->face_clockwise->companion->face_clockwise->face_clockwise;
554
 
                m_last_factor.erase(clockwise->companion->face_clockwise->companion);
555
 
                m_split_edges.erase(clockwise->companion->face_clockwise->companion);
556
 
        }
557
 
        k3d::split_edge* companion = Edge.companion;
558
 
        if(!companion) {
559
 
                companion = new k3d::split_edge(clockwise->vertex, clockwise->companion->face_clockwise);
560
 
                k3d::join_edges(*companion, Edge);
561
 
                m_Polyhedron.edges.push_back(companion);
562
 
        }
563
 
        companion->face_clockwise = clockwise->companion->face_clockwise;
564
 
        clockwise->companion->face_clockwise = companion;
565
 
        edge_face_map::iterator it = m_face_starts.find(Edge.companion);
566
 
        if(it != m_face_starts.end()) {
567
 
                k3d::face* removed_face = it->second;
568
 
                removed_face->first_edge = companion->face_clockwise->companion;
569
 
                m_face_starts.erase(it);
570
 
                m_face_starts[companion->face_clockwise->companion] = removed_face;
571
 
        }
572
 
 
573
 
        return companion;
574
 
}
575
 
 
576
 
// Detach the starting point of a parallel split face, where the detached vertex belongs to Edge.
577
 
k3d::split_edge* splitter::detach_edge_vertex(k3d::split_edge& Edge, const k3d::vector3& centroid)
578
 
{
579
 
        std::cerr << debug << "detach_edge_vertex" << std::endl;
580
 
        k3d::split_edge* c_clockwise = counter_clockwise(Edge);
581
 
        k3d::split_edge* other_edge = counter_clockwise(*(c_clockwise->companion));
582
 
        //double f = adapt_factor(*c_clockwise, m_f);
583
 
        double f = 2*sqrt(m_f * m_parallel_edges[c_clockwise]);
584
 
        f = f > 1.0 ? 1.0 : f;
585
 
        std::cerr << debug << "Moving [" << Edge.vertex->position[0] << ", " << Edge.vertex->position[1] << ", " << Edge.vertex->position[2] << "] to [";
586
 
        //Edge.vertex->position = k3d::mix(Edge.vertex->position, c_clockwise->vertex->position, f);
587
 
        Edge.vertex->position = k3d::mix(Edge.face_clockwise->vertex->position, centroid, f);
588
 
        m_other_points.erase(Edge.vertex);
589
 
        std::cerr << debug << Edge.vertex->position[0] << ", " << Edge.vertex->position[1] << ", " << Edge.vertex->position[2] << "]" << std::endl;
590
 
        m_last_factor[c_clockwise] = f;
591
 
        k3d::split_edge* companion = Edge.companion;
592
 
        if(companion) {
593
 
                k3d::split_edge* companion_ccl = counter_clockwise(*companion);
594
 
                companion->face_clockwise->vertex = Edge.face_clockwise->vertex;
595
 
                m_last_factor.erase(companion->face_clockwise);
596
 
                m_split_edges.erase(companion->face_clockwise);
597
 
                companion_ccl->face_clockwise = companion->face_clockwise;
598
 
        } else {
599
 
                companion = new k3d::split_edge(Edge.face_clockwise->vertex, c_clockwise->companion);
600
 
                k3d::join_edges(Edge, *companion);
601
 
                m_Polyhedron.edges.push_back(companion);
602
 
        }
603
 
        companion->face_clockwise = c_clockwise->companion;
604
 
        other_edge->face_clockwise = companion;
605
 
        m_last_factor.erase(other_edge);
606
 
        m_split_edges.erase(other_edge);
607
 
        edge_face_map::iterator it = m_face_starts.find(Edge.companion);
608
 
        if(it != m_face_starts.end()) {
609
 
                k3d::face* removed_face = it->second;
610
 
                removed_face->first_edge = other_edge->companion;
611
 
                m_face_starts.erase(it);
612
 
                m_face_starts[other_edge->companion] = removed_face;
613
 
        }
614
 
        return companion->face_clockwise;
615
 
}
616
 
 
617
 
k3d::split_edge* splitter::split_face_along_edge(k3d::split_edge& Edge, const double factor, const k3d::vector3& centroid)
618
 
{
619
 
        m_f = factor;
620
 
        // get the two neigbour edges
621
 
        k3d::split_edge* clockwise = Edge.face_clockwise;
622
 
        k3d::split_edge* c_clockwise = counter_clockwise(Edge);
623
 
        // Check if the clockwise edge is new
624
 
        bool is_new = false;
625
 
        bool is_new_companion = false;
626
 
        bool is_new_cc = false;
627
 
        k3d::split_edge* other_end = 0;
628
 
        if(m_parallel_edges.find(clockwise) != m_parallel_edges.end())
629
 
                is_new = true;
630
 
        if(m_parallel_edges.find(clockwise->companion) != m_parallel_edges.end())
631
 
                is_new_companion = true;
632
 
        if(Edge.face_clockwise->companion && Edge.face_clockwise->companion->face_clockwise->face_clockwise->companion &&  (m_parallel_edges.find(Edge.face_clockwise->companion->face_clockwise->face_clockwise->companion) != m_parallel_edges.end())) {
633
 
                is_new_cc = true;
634
 
                other_end = Edge.face_clockwise->companion->face_clockwise->face_clockwise->companion->face_clockwise;
635
 
        }
636
 
        k3d::split_edge* new_ccl_edge = 0;
637
 
        k3d::split_edge* new_cl_edge = 0;
638
 
        if(is_new || is_new_companion || is_new_cc) {
639
 
                if(is_new) {
640
 
                        std::cerr << debug << "is_new" << std::endl;
641
 
                        new_ccl_edge = detach_edge_novertex(Edge, centroid);
642
 
                        if(!is_new_cc) {
643
 
                                new_cl_edge = this->split_edge(*(Edge.companion->face_clockwise->face_clockwise), factor);
644
 
                                m_last_factor[new_cl_edge] = factor;
645
 
                                m_split_edges.insert(Edge.companion->face_clockwise->face_clockwise);
646
 
                        }
647
 
                }
648
 
                if(is_new_companion) {
649
 
                        std::cerr << debug << "is_new_companion" << std::endl;
650
 
                        new_cl_edge = detach_edge_vertex(*(Edge.face_clockwise->companion->face_clockwise), centroid);
651
 
                        if(!is_new_cc) {
652
 
                                new_ccl_edge = this->split_edge(*c_clockwise, 1-factor);
653
 
                                m_last_factor[c_clockwise] = factor;
654
 
                                m_split_edges.insert(new_ccl_edge);
655
 
                                if(c_clockwise == new_ccl_edge)
656
 
                                        c_clockwise = counter_clockwise(*c_clockwise);
657
 
                        }
658
 
                }
659
 
                if(is_new_cc) {
660
 
                        std::cerr << debug << "is_new_cc" << std::endl;
661
 
                        new_cl_edge = detach_edge_vertex(*other_end, centroid);
662
 
                }
663
 
                clockwise = counter_clockwise(*new_cl_edge);
664
 
                c_clockwise = counter_clockwise(*new_ccl_edge);
665
 
        } else {
666
 
                // split neighbour edges at the desired length
667
 
                new_ccl_edge = this->split_edge(*c_clockwise, 1-factor);
668
 
                m_last_factor[c_clockwise] = factor;
669
 
                m_split_edges.insert(new_ccl_edge);
670
 
                if(c_clockwise == new_ccl_edge)
671
 
                        c_clockwise = counter_clockwise(*c_clockwise);
672
 
                new_cl_edge = this->split_edge(*clockwise, factor);
673
 
                m_last_factor[new_cl_edge] = factor;
674
 
                m_split_edges.insert(clockwise);
675
 
        }
676
 
        // create new edges
677
 
        k3d::split_edge* new_edge = new k3d::split_edge(new_ccl_edge->vertex, new_cl_edge);
678
 
        k3d::split_edge* new_edge_companion = new k3d::split_edge(new_cl_edge->vertex, new_ccl_edge);
679
 
        // add them to the list
680
 
        m_Polyhedron.edges.push_back(new_edge);
681
 
        m_Polyhedron.edges.push_back(new_edge_companion);
682
 
        // join them
683
 
        k3d::join_edges(*new_edge, *new_edge_companion);
684
 
        // fix the other face_clockwise pointers
685
 
        clockwise->face_clockwise = new_edge_companion;
686
 
        c_clockwise->face_clockwise = new_edge;
 
796
        }
 
797
        m_Polyhedron.edges.push_back(new_edge);
 
798
        return add_t_point(new_point, &Edge, Edge.face_clockwise);
 
799
}
 
800
 
 
801
void splitter::split_edge_add_point(k3d::split_edge& Edge, const double factor, point* Start, point* End)
 
802
{
 
803
        point* p = split_edge(Edge, factor, Start, End);
 
804
        m_Points.push_back(p->vertex);
 
805
}
 
806
 
 
807
void splitter::split_near(k3d::split_edge& edge, const double factor)
 
808
{
 
809
        point* far_point = far(*companion(edge));
 
810
        if (far_point)
 
811
        {
 
812
                k3d::vector3 new_pos = k3d::mix(start(edge)->vertex->position, end(edge)->vertex->position, factor);
 
813
                far_point->vertex->position = k3d::mix(new_pos, far_point->vertex->position, 0.5);
 
814
                set_near(edge, *(add_t_point(far_point->vertex, 0, 0)));
 
815
        }
 
816
        else
 
817
        {
 
818
                point* new_point = split_edge(edge, factor, start(edge), end(edge));
 
819
                m_Points.push_back(new_point->vertex);
 
820
                set_near(edge, *new_point);
 
821
        }
 
822
}
 
823
 
 
824
void splitter::split_far(k3d::split_edge& edge, const double factor)
 
825
{
 
826
        point* near_point = near(*companion(edge));
 
827
        if (near_point)
 
828
        {
 
829
                k3d::vector3 new_pos = k3d::mix(start(edge)->vertex->position, end(edge)->vertex->position, factor);
 
830
                near_point->vertex->position = k3d::mix(new_pos, near_point->vertex->position, 0.5);
 
831
                set_far(edge, *(add_t_point(near_point->vertex, 0, 0)));
 
832
        }
 
833
        else if (near(edge))
 
834
        {
 
835
                point* new_point = split_edge(*(edge.face_clockwise), factor, start(edge), end(edge));
 
836
                m_Points.push_back(new_point->vertex);
 
837
                set_far(edge, *new_point);
 
838
        }
 
839
        else
 
840
        {
 
841
                point* new_point = split_edge(edge, factor, start(edge), end(edge));
 
842
                m_Points.push_back(new_point->vertex);
 
843
                set_far(edge, *new_point);
 
844
        }
 
845
}
 
846
 
 
847
void splitter::make_creases()
 
848
{
 
849
        // add the new points
 
850
        for (faces_t::iterator face = m_faces.begin(); face != m_faces.end(); ++face)
 
851
        {
 
852
                k3d::split_edge* first_edge = face->first;
 
853
                k3d::split_edge* this_edge = first_edge;
 
854
                bool start = true;
 
855
                while (this_edge != first_edge || start)
 
856
                {
 
857
                        edges_t::iterator edge = find_info(*this_edge);
 
858
                        double sharpness = get_sharpness(*(edge->first));
 
859
                        double cl_sharpness = get_sharpness(*(edge->second.second[0]));
 
860
                        if (sharpness > 0.0)
 
861
                        {
 
862
                                if (cl_sharpness > 0.0)
 
863
                                {
 
864
                                        // Use the geometric mean of both factors to calculate the factor for lerping between the centroid and the corner
 
865
                                        double f = 2*sqrt(sharpness_to_factor(sharpness) * sharpness_to_factor(cl_sharpness));
 
866
                                        k3d::vector3 face_pos(k3d::mix<k3d::vector3>(edge->second.second[0]->vertex->position, edge->second.first[1]->vertex->position, f));
 
867
                                        point* face_vertex = add_point(new k3d::point(face_pos));
 
868
                                        m_Points.push_back(face_vertex->vertex);
 
869
                                        set_face_vertex(*(edge->second.second[0]), *face_vertex);
 
870
                                        if (!companion(*(edge->second.second[0])) || get_sharpness(*clockwise(*companion(*(edge->second.second[0])))) > 0.0)
 
871
                                        {
 
872
                                                // the clockwise edge
 
873
                                                split_near(*(edge->second.second[0]),sharpness_to_factor(sharpness));
 
874
                                                // the edge itself
 
875
                                                split_far(*(edge->first), 1-sharpness_to_factor(cl_sharpness));
 
876
                                        }
 
877
                                        else if (get_sharpness(*counter_clockwise(*companion(*(edge->first)))))
 
878
                                        {
 
879
                                                // the clockwise edge
 
880
                                                split_near(*(edge->second.second[0]),sharpness_to_factor(sharpness));
 
881
                                                // the edge itself
 
882
                                                split_far(*(edge->first), 1-sharpness_to_factor(cl_sharpness));
 
883
                                        }
 
884
                                }
 
885
                                else
 
886
                                {
 
887
                                        split_near(*(edge->second.second[0]),sharpness_to_factor(sharpness));
 
888
                                }
 
889
                        }
 
890
                        else if (cl_sharpness > 0.0)
 
891
                        {
 
892
                                split_far(*(edge->first), 1-sharpness_to_factor(cl_sharpness));
 
893
                        }
 
894
                        start = false;
 
895
                        this_edge = clockwise(*this_edge);
 
896
                }
 
897
        }
 
898
 
 
899
        // correct clockwise and counter-clockwise edges
 
900
        for (faces_t::iterator face = m_faces.begin(); face != m_faces.end(); ++face)
 
901
        {
 
902
                k3d::split_edge* first_edge = face->first;
 
903
                k3d::split_edge* this_edge = first_edge;
 
904
                bool start = true;
 
905
                while (this_edge != first_edge || start)
 
906
                {
 
907
                        point* end_v = end(*this_edge);
 
908
                        point* near_v = near(*this_edge);
 
909
                        point* far_v = far(*this_edge);
 
910
                        point* companion_far_v = far(*companion(*this_edge));
 
911
                        point* companion_near_v = near(*companion(*this_edge));
 
912
                        if (near_v || companion_far_v)
 
913
                        {
 
914
                                if (near_v)
 
915
                                {
 
916
                                        near_v->links[0]->counter_clockwise->edge = this_edge;
 
917
                                        near_v->links[0]->companion_clockwise->edge = this_edge->face_clockwise;
 
918
                                }
 
919
                                if (far_v || companion_near_v)
 
920
                                {
 
921
                                        if (far_v)
 
922
                                        {
 
923
                                                far_v->links[0]->counter_clockwise->edge = this_edge->face_clockwise;
 
924
                                                far_v->links[0]->companion_clockwise->edge = this_edge->face_clockwise->face_clockwise;
 
925
                                        }
 
926
                                                end_v->links[0]->counter_clockwise->edge = this_edge->face_clockwise->face_clockwise;
 
927
                                }
 
928
                                else
 
929
                                {
 
930
                                        end_v->links[0]->counter_clockwise->edge = this_edge->face_clockwise;
 
931
                                }
 
932
                        }
 
933
                        else if (far_v || companion_near_v)
 
934
                        {
 
935
                                if (far_v)
 
936
                                {
 
937
                                        far_v->links[0]->counter_clockwise->edge = this_edge;
 
938
                                        far_v->links[0]->companion_clockwise->edge = this_edge->face_clockwise;
 
939
                                }
 
940
                                end_v->links[0]->counter_clockwise->edge = this_edge->face_clockwise;
 
941
                        }
 
942
                        start = false;
 
943
                        this_edge = clockwise(*this_edge);
 
944
                }
 
945
                
 
946
                this_edge = first_edge;
 
947
                start = true;
 
948
                // connect the new points
 
949
                while (this_edge != first_edge || start)
 
950
                {
 
951
                        point* face_v = face_vertex(*this_edge);
 
952
                        point* near_v = near(*this_edge);
 
953
                        point* far_v = far(*this_edge);
 
954
                        point* start_v = this->start(*this_edge);
 
955
                        point* next_face_v = face_vertex(*clockwise(*this_edge));
 
956
                        point* next_near_v = 0;
 
957
                        if (face_v && !next_face_v)
 
958
                                next_near_v = near(*clockwise(*this_edge));
 
959
                        if (face_v)
 
960
                        {
 
961
                                if (near_v)
 
962
                                {
 
963
                                        link* l = near_v->join(face_v);
 
964
                                        m_Polyhedron.edges.push_back(l->edge);
 
965
                                        m_Polyhedron.edges.push_back(l->companion->edge);
 
966
                                }
 
967
                                if (far_v)
 
968
                                {
 
969
                                        if (next_face_v)
 
970
                                        {
 
971
                                                link* l = next_face_v->join(face_v);
 
972
                                                m_Polyhedron.edges.push_back(l->edge);
 
973
                                                m_Polyhedron.edges.push_back(l->companion->edge);
 
974
                                                l = far_v->join(next_face_v);
 
975
                                                m_Polyhedron.edges.push_back(l->edge);
 
976
                                                m_Polyhedron.edges.push_back(l->companion->edge);
 
977
                                        }
 
978
                                }
 
979
                        }
 
980
                        if (face_v && !near_v && !far(*counter_clockwise(*this_edge)))
 
981
                        {
 
982
                                link* l = start_v->join(face_v);
 
983
                                m_Polyhedron.edges.push_back(l->edge);
 
984
                                m_Polyhedron.edges.push_back(l->companion->edge);
 
985
                                k3d::vector3 n = k3d::normal(this_edge);
 
986
                                face_v->reorder_on(n);
 
987
                        }
 
988
                        if (face_v && next_face_v && !far_v)
 
989
                        {
 
990
                                link* l = face_v->join(next_face_v);
 
991
                                m_Polyhedron.edges.push_back(l->edge);
 
992
                                m_Polyhedron.edges.push_back(l->companion->edge);
 
993
                        }
 
994
                        if (!face_v && far_v && next_face_v)
 
995
                        {
 
996
                                link* l = far_v->join(next_face_v);
 
997
                                m_Polyhedron.edges.push_back(l->edge);
 
998
                                m_Polyhedron.edges.push_back(l->companion->edge);
 
999
                                k3d::vector3 n = k3d::normal(this_edge);
 
1000
                                next_face_v->reorder_on(n);
 
1001
                        }
 
1002
                        if (!next_face_v && far_v)
 
1003
                        {
 
1004
                                point* next_v = face_vertex(*clockwise(*clockwise(*this_edge)));
 
1005
                                if (next_v)
 
1006
                                {
 
1007
                                        link* l = next_v->join(far_v);
 
1008
                                        m_Polyhedron.edges.push_back(l->edge);
 
1009
                                        m_Polyhedron.edges.push_back(l->companion->edge);
 
1010
                                }
 
1011
                        }
 
1012
                        point* last_far_v = far(*counter_clockwise(*this_edge));
 
1013
                        if (!next_face_v && !face_v && last_far_v)
 
1014
                        {
 
1015
                                link* l = last_far_v->join(near(*clockwise(*this_edge)));
 
1016
                                m_Polyhedron.edges.push_back(l->edge);
 
1017
                                m_Polyhedron.edges.push_back(l->companion->edge);
 
1018
                        }
 
1019
 
 
1020
                        if (next_near_v)
 
1021
                        {
 
1022
                                link* l = next_near_v->join(face_v);
 
1023
                                m_Polyhedron.edges.push_back(l->edge);
 
1024
                                m_Polyhedron.edges.push_back(l->companion->edge);
 
1025
                        }
 
1026
                        start = false;
 
1027
                        this_edge = clockwise(*this_edge);
 
1028
                } // end while (face loop)
 
1029
                
 
1030
                this_edge = first_edge;
 
1031
                start = true;
 
1032
                // update all links
 
1033
                while (this_edge != first_edge || start)
 
1034
                {
 
1035
                        point* face_v = face_vertex(*this_edge);
 
1036
                        point* near_v = near(*this_edge);
 
1037
                        point* far_v = far(*this_edge);
 
1038
                        if (face_v)
 
1039
                        {
 
1040
                                face_v->update();
 
1041
                        }
 
1042
                        if (near_v)
 
1043
                        {
 
1044
                                near_v->update();
 
1045
                        }
 
1046
                        if (far_v)
 
1047
                        {
 
1048
                                far_v->update();
 
1049
                        }
 
1050
                        start = false;
 
1051
                        this_edge = clockwise(*this_edge);
 
1052
                } // end while (face loop)
 
1053
                
 
1054
                this_edge = first_edge;
 
1055
                start = true;
 
1056
                // complete the k3d::split_edges in the links
 
1057
                while (this_edge != first_edge || start)
 
1058
                {
 
1059
                        point* face_v = face_vertex(*this_edge);
 
1060
                        point* near_v = near(*this_edge);
 
1061
                        point* far_v = far(*this_edge);
 
1062
                        if (face_v)
 
1063
                        {
 
1064
                                face_v->complete();
 
1065
                        }
 
1066
                        if (near_v)
 
1067
                        {
 
1068
                                near_v->complete();
 
1069
                        }
 
1070
                        if (far_v)
 
1071
                        {
 
1072
                                far_v->complete();
 
1073
                        }
 
1074
                        start = false;
 
1075
                        this_edge = clockwise(*this_edge);
 
1076
                } // end while (face loop)
 
1077
        } // end for (all faces)
 
1078
 
687
1079
        // add new faces
688
 
        if(!is_face(*new_edge)) {
689
 
                add_face(*new_edge);
690
 
        } else {
691
 
                add_face(*new_edge_companion);
692
 
        }
693
 
        m_parallel_edges[new_edge_companion] = factor;
694
 
        if(is_new)
695
 
                m_last_factor[new_edge_companion] = m_parallel_edges[(counter_clockwise(*new_edge))->companion];
696
 
        if(is_new_companion)
697
 
                m_last_factor[new_edge_companion] = m_parallel_edges[new_edge->face_clockwise->companion];
698
 
        std::cerr << debug << "Created parallel edge [" << new_edge_companion->vertex->position[0] << ", " << new_edge_companion->vertex->position[1] << ", " << new_edge_companion->vertex->position[2] << "]->[" << new_edge->vertex->position[0] << ", " << new_edge->vertex->position[1] << ", " << new_edge->vertex->position[2] << "]" << std::endl;
699
 
        return new_edge_companion;
 
1080
        for (k3d::polyhedron::edges_t::iterator edge = m_Polyhedron.edges.begin(); edge != m_Polyhedron.edges.end(); ++edge)
 
1081
        {
 
1082
                add_face(*(*edge));
 
1083
        }
 
1084
}
 
1085
 
 
1086
void splitter::link_points(point* A, point* B)
 
1087
{
 
1088
        return_if_fail(A || B || A->vertex || B->vertex);
 
1089
        link* l = A->join(B);
 
1090
        m_Polyhedron.edges.push_back(l->edge);
 
1091
        m_Polyhedron.edges.push_back(l->companion->edge);
 
1092
        A->update();
 
1093
        B->update();
 
1094
        A->complete();
 
1095
        B->complete();
 
1096
        add_face(*(l->edge));
 
1097
        add_face(*(l->companion->edge));
 
1098
}
 
1099
 
 
1100
void splitter::link_points()
 
1101
{
 
1102
        for (faces_t::iterator face = m_faces.begin(); face != m_faces.end(); ++face)
 
1103
        {
 
1104
                k3d::split_edge* first_edge = face->first;
 
1105
                k3d::split_edge* this_edge = first_edge;
 
1106
                bool start = true;
 
1107
                std::vector<point*> points;
 
1108
                while (this_edge != first_edge || start)
 
1109
                {
 
1110
                        if (this_edge->vertex->selected && (!this_edge->face_clockwise->vertex->selected || this_edge->face_clockwise->face_clockwise->vertex->selected))
 
1111
                                points.push_back(this->start(*this_edge));
 
1112
                        start = false;
 
1113
                        this_edge = clockwise(*this_edge);
 
1114
                }
 
1115
                if (points.size() == 2)
 
1116
                        link_points(points[0], points[1]);
 
1117
        }
 
1118
}
 
1119
 
 
1120
void splitter::split_face_parallel(k3d::split_edge& Edge, double Factor)
 
1121
{
 
1122
        return_if_fail(&Edge);
 
1123
        return_if_fail(Edge.face_clockwise);
 
1124
        // get the counter-clockwise edge
 
1125
        k3d::split_edge* ccl;
 
1126
        for(ccl = &Edge; ccl && ccl->face_clockwise; ccl = ccl->face_clockwise)
 
1127
        {
 
1128
                if (ccl->face_clockwise == &Edge)
 
1129
                        break;
 
1130
        }
 
1131
        point* start = split_edge(*ccl, 1-Factor);
 
1132
        m_Points.push_back(start->vertex);
 
1133
        point* end = split_edge(*(Edge.face_clockwise), Factor);
 
1134
        m_Points.push_back(end->vertex);
 
1135
        link_points(start, end);
 
1136
}
 
1137
 
 
1138
splitter::edges_t::iterator& splitter::find_info(k3d::split_edge& Edge)
 
1139
{
 
1140
        if (&Edge == m_cached_edge.first)
 
1141
                return m_cached_edge.second;
 
1142
        m_cached_edge.first = &Edge;
 
1143
        m_cached_edge.second = m_edges.find(&Edge);
 
1144
        return m_cached_edge.second;
 
1145
}
 
1146
 
 
1147
k3d::split_edge* splitter::get_edge(k3d::split_edge& Edge, int Index)
 
1148
{
 
1149
        edges_t::iterator edge = find_info(Edge);
 
1150
        if (edge != m_edges.end())
 
1151
        {
 
1152
                return edge->second.second[Index];
 
1153
        }
 
1154
        return 0;
 
1155
}
 
1156
 
 
1157
k3d::split_edge* splitter::clockwise(k3d::split_edge& Edge)
 
1158
{
 
1159
        return get_edge(Edge, 0);
700
1160
}
701
1161
 
702
1162
k3d::split_edge* splitter::counter_clockwise(k3d::split_edge& Edge)
703
1163
{
704
 
        k3d::split_edge* last_edge = &Edge;
705
 
        k3d::split_edge* this_edge = Edge.face_clockwise;
706
 
 
707
 
        while(this_edge != &Edge)
708
 
                {
709
 
                        last_edge = this_edge;
710
 
                        this_edge = this_edge->face_clockwise;
711
 
                }
712
 
 
713
 
        return last_edge;
 
1164
        return get_edge(Edge, 1);
 
1165
}
 
1166
 
 
1167
k3d::split_edge* splitter::companion(k3d::split_edge& Edge)
 
1168
{
 
1169
        return get_edge(Edge, 2);
 
1170
}
 
1171
 
 
1172
point* splitter::get_point(k3d::split_edge& Edge, int Index)
 
1173
{
 
1174
        edges_t::iterator edge = find_info(Edge);
 
1175
        if (edge != m_edges.end())
 
1176
        {
 
1177
                return edge->second.first[Index];
 
1178
        }
 
1179
        return 0;
 
1180
}
 
1181
 
 
1182
point* splitter::start(k3d::split_edge& Edge)
 
1183
{
 
1184
        return get_point(Edge, 0);
 
1185
}
 
1186
 
 
1187
point* splitter::end(k3d::split_edge& Edge)
 
1188
{
 
1189
        return start(*clockwise(Edge));
 
1190
}
 
1191
 
 
1192
k3d::point* splitter::centroid(k3d::split_edge& Edge)
 
1193
{
 
1194
        return get_point(Edge, 1)->vertex;
 
1195
}
 
1196
 
 
1197
point* splitter::near(k3d::split_edge& Edge)
 
1198
{
 
1199
        return get_point(Edge, 2);
 
1200
}
 
1201
 
 
1202
point* splitter::far(k3d::split_edge& Edge)
 
1203
{
 
1204
        return get_point(Edge, 3);
 
1205
}
 
1206
 
 
1207
point* splitter::face_vertex(k3d::split_edge& Edge)
 
1208
{
 
1209
        return get_point(Edge, 4);
 
1210
}
 
1211
 
 
1212
void splitter::set_point(k3d::split_edge& Edge, point& Point, int Index)
 
1213
{
 
1214
        edges_t::iterator edge = find_info(Edge);
 
1215
        if (edge != m_edges.end())
 
1216
        {
 
1217
                edge->second.first[Index] = &Point;
 
1218
        }
 
1219
}
 
1220
 
 
1221
void splitter::set_near(k3d::split_edge& Edge, point& Point)
 
1222
{
 
1223
        set_point(Edge, Point, 2);
 
1224
}
 
1225
 
 
1226
void splitter::set_far(k3d::split_edge& Edge, point& Point)
 
1227
{
 
1228
        set_point(Edge, Point, 3);
 
1229
}
 
1230
 
 
1231
void splitter::set_face_vertex(k3d::split_edge& Edge, point& Point)
 
1232
{
 
1233
        set_point(Edge, Point, 4);
714
1234
}
715
1235
 
716
1236
bool splitter::is_face(k3d::split_edge& Edge)
720
1240
 
721
1241
        while(this_edge != &Edge)
722
1242
                {
723
 
                        if(m_face_starts.find(last_edge) != m_face_starts.end())
 
1243
                        if(m_all_faces.find(last_edge) != m_all_faces.end())
 
1244
                        {
724
1245
                                return true;
 
1246
                        }
725
1247
 
726
1248
                        last_edge = this_edge;
727
 
                        this_edge = this_edge->face_clockwise;
 
1249
                        if (this_edge)
 
1250
                                this_edge = this_edge->face_clockwise;
 
1251
                        else
 
1252
                                return true;
728
1253
                }
729
1254
 
730
 
        return (m_face_starts.find(last_edge) != m_face_starts.end());
 
1255
        return (m_all_faces.find(last_edge) != m_all_faces.end());
731
1256
}
732
1257
 
733
1258
void splitter::add_face(k3d::split_edge& Edge)
734
1259
{
735
 
        k3d::face* new_face = new k3d::face(&Edge);
736
 
        m_Polyhedron.faces.push_back(new_face);
737
 
        m_face_starts[&Edge] = new_face;
738
 
}
739
 
 
740
 
double splitter::adapt_factor(k3d::split_edge& Edge, const double factor)
741
 
{
742
 
        double f = factor;
743
 
        double f2 = -1.0;
744
 
        edge_double_map::iterator it = m_last_factor.find(&Edge);
745
 
 
746
 
        if(it != m_last_factor.end())
747
 
                f2 = it->second;
748
 
        else
749
 
                {
750
 
                        it = m_last_factor.find(Edge.companion);
751
 
                        if(it != m_last_factor.end())
752
 
                                f2 = (it->second);
753
 
                }
754
 
 
755
 
        if(f2 != -1.0)
756
 
                {
757
 
                        if(f < 0.5)
758
 
                                f /= 1-f2;
759
 
                        else
760
 
                                f = 1 - f2/f;
761
 
                }
762
 
 
763
 
        if(f > 1.0)
764
 
                f = 1.0;
765
 
        std::cerr << debug << "Factor " << f << " instead of " << factor << "." << std::endl;
766
 
 
767
 
        return f;
 
1260
        if (!(is_face(Edge)))
 
1261
        {
 
1262
                k3d::face* new_face = new k3d::face(&Edge);
 
1263
                m_Polyhedron.faces.push_back(new_face);
 
1264
                m_all_faces[&Edge] = new_face;
 
1265
        }
 
1266
}
 
1267
 
 
1268
point* splitter::add_point(k3d::point* Point)
 
1269
{
 
1270
        point* p = new point(Point);
 
1271
        m_added_points.push_back(p);
 
1272
        return p;
 
1273
}
 
1274
 
 
1275
point* splitter::add_t_point(k3d::point* Point, k3d::split_edge* To, k3d::split_edge* From, bool dummy_edge)
 
1276
{
 
1277
        point* p = new t_point(Point, To, From, dummy_edge);
 
1278
        m_added_points.push_back(p);
 
1279
        return p;
768
1280
}
769
1281
 
770
1282
double get_sharpness(const k3d::split_edge& Edge)
773
1285
        {
774
1286
                if(tag->first == "crease" && (tag->second.type() == typeid(k3d::ri::real)))
775
1287
                {
776
 
                        std::cerr << debug << "Found sharpness " << boost::any_cast<double>(tag->second) << " on [" << Edge.vertex->position[0] << ", " << Edge.vertex->position[1] << ", " << Edge.vertex->position[2] << "]->[" << Edge.face_clockwise->vertex->position[0] << ", " << Edge.face_clockwise->vertex->position[1] << ", " << Edge.face_clockwise->vertex->position[2] << "]" << std::endl;
777
1288
                        return boost::any_cast<double>(tag->second);
778
1289
                }
779
1290
        }
780
 
 
781
 
        std::cerr << debug << "Found no sharpness on [" << Edge.vertex->position[0] << ", " << Edge.vertex->position[1] << ", " << Edge.vertex->position[2] << "]->[" << Edge.face_clockwise->vertex->position[0] << ", " << Edge.face_clockwise->vertex->position[1] << ", " << Edge.face_clockwise->vertex->position[2] << "]" << std::endl;
782
1291
        return 0.0;
783
1292
}
784
1293
 
785
 
k3d::vector3 get_centroid(const k3d::split_edge& Edge)
786
 
{
787
 
        k3d::vector3 centroid = Edge.vertex->position;
788
 
        unsigned long edges = 1;
789
 
        const k3d::split_edge* last_edge = &Edge;
790
 
        const k3d::split_edge* this_edge = Edge.face_clockwise;
791
 
        while(this_edge != &Edge)
792
 
                {
793
 
                        ++edges;
794
 
                        centroid += this_edge->vertex->position;
795
 
                        last_edge = this_edge;
796
 
                        this_edge = this_edge->face_clockwise;
797
 
                }
798
 
 
799
 
        return centroid / edges;
800
 
}
801
 
 
802
1294
void crease(const k3d::mesh& Input, k3d::mesh& Output)
803
1295
{
804
1296
        k3d::deep_copy(Input, Output);
805
1297
        for(k3d::mesh::polyhedra_t::iterator it = Output.polyhedra.begin(); it != Output.polyhedra.end(); ++it)
806
1298
        {
807
 
                //if((*it)->type == k3d::polyhedron::CATMULL_CLARK_SUBDIVISION_MESH)
808
1299
                k3d::polyhedron& Polyhedron = **it;
809
1300
                return_if_fail(k3d::is_valid(Polyhedron));
810
1301
                splitter Splitter(Polyhedron, Output.points);
811
 
                unsigned long len = Polyhedron.faces.size();
812
 
                for(unsigned long i = 0; i < len; ++i)
813
 
                {
814
 
                        std::vector<k3d::split_edge*> edges;
815
 
                        k3d::split_edge* first = Polyhedron.faces[i]->first_edge;
816
 
                        edges.push_back(first);
817
 
                        k3d::split_edge* next = first->face_clockwise;
818
 
                        while(next != first)
819
 
                                {
820
 
                                        edges.push_back(next);
821
 
                                        next = next->face_clockwise;
822
 
                                }
823
 
 
824
 
                        std::cerr << debug << "Face has " << edges.size() << " edges." << std::endl;
825
 
                        unsigned long elen = edges.size();
826
 
                        k3d::vector3 centroid(0,0,0);
827
 
 
828
 
                        for(unsigned long j = 0; j < elen; ++j)
829
 
                                centroid += edges[j]->vertex->position;
830
 
 
831
 
                        centroid /= elen;
832
 
 
833
 
                        for(unsigned long j = 0; j < elen; ++j)
834
 
                        {
835
 
                                k3d::split_edge& edge = *(edges[j]);
836
 
                                double s = get_sharpness(edge);
837
 
                                if(s > 0)
838
 
                                {
839
 
                                        Splitter.split_face_along_edge(edge,splitter::sharpness_to_factor(s), centroid);
840
 
                                        edge.tags["crease"] = 0.0;
841
 
                                }
842
 
                        }
843
 
                }
844
 
 
 
1302
                Splitter.make_creases();
 
1303
 
 
1304
                // remove crease info to avoid calculating creases twice
845
1305
                for(unsigned long j = 0; j < Polyhedron.edges.size(); ++j)
846
1306
                        Polyhedron.edges[j]->tags.erase("crease");
847
1307
 
849
1309
        }
850
1310
}
851
1311
 
 
1312
void split_faces_parallel(const k3d::mesh& Input, k3d::mesh& Output, const double Factor)
 
1313
{
 
1314
        k3d::deep_copy(Input, Output);
 
1315
        for(k3d::mesh::polyhedra_t::iterator it = Output.polyhedra.begin(); it != Output.polyhedra.end(); ++it)
 
1316
        {
 
1317
                k3d::polyhedron& Polyhedron = **it;
 
1318
                return_if_fail(k3d::is_valid(Polyhedron));
 
1319
                splitter Splitter(Polyhedron, Output.points);
 
1320
                std::vector<k3d::split_edge*> selected_edges;
 
1321
                for (k3d::polyhedron::edges_t::iterator edge = Polyhedron.edges.begin(); edge != Polyhedron.edges.end(); ++edge)
 
1322
                {
 
1323
                        if ((*edge)->selected)
 
1324
                                selected_edges.push_back(*edge);
 
1325
                }
 
1326
                for (std::vector<k3d::split_edge*>::iterator edge = selected_edges.begin(); edge != selected_edges.end(); ++edge)
 
1327
                        Splitter.split_face_parallel(*(*edge), Factor);
 
1328
 
 
1329
                return_if_fail(k3d::is_valid(Polyhedron));
 
1330
        }
 
1331
}
852
1332
} // namespace subdiv
853
 
 
854